目录
一、多态
1. 多态的定义:
2. 多态存在的三个必要条件
3. 多态的格式:
4. 多态的案例
5. 多态的好处
6. 多态的弊端
7. 引用类型转换
1. 向上转型(自动转换)
2. 向下转型(强制转换)
3. instanceof关键字
二、链表
1、基础
2、复杂度
3、插入元素
4、删除元素
1.找到cur的上一个节点pre。
2.将pre的next指向cur的next即可(cur的next是否删除按具体情况处理)。
三、学习心得
一、多态
1. 多态的定义:
-
多态是指同一个行为具有多个不同表现形式或形态的能力。
-
多态就是同一个接口,使用不同的实例而执行不同操作。
多态是指同一个行为具有多个不同表现形式或形态的能力。
多态就是同一个接口,使用不同的实例而执行不同操作。
就举动物类的例子吧,cat和dog都是属于动物这一类,而动物呢,都有一个共同的行为就是吃吧,而不同的动物所吃的食物都大不相同吧!
猫喜欢吃鱼! 而对于狗就比较喜欢啃骨头!
所以多态就是对于吃这一行为来说,每种动物对吃这一行为所表现的行为都不尽相同。
2. 多态存在的三个必要条件
-
继承或者实现
在多态中必须存在有继承或者实现关系的子类和父类。
-
方法的重写
子类对父类中某些方法进行重新定义(重写),在调用这些方法时就会调用子类的方法。
-
基类引用指向派生类对象,即父类引用指向子类对象
父类类型:指子类对象继承的父类类型,或者实现的父接口类型。
-
继承或者实现
在多态中必须存在有继承或者实现关系的子类和父类。
-
方法的重写
子类对父类中某些方法进行重新定义(重写),在调用这些方法时就会调用子类的方法。
-
基类引用指向派生类对象,即父类引用指向子类对象
父类类型:指子类对象继承的父类类型,或者实现的父接口类型。
3. 多态的格式:
父类类型 变量名 = new 子类类型();
变量名.方法名();
多态格式可以充分体现了同一个接口,使用不同的实例而执行不同操作。
4. 多态的案例
多态我们首先要知道的一点:
当使用多态方式调用方法时,首先检查父类中是否有该方法,如果没有,则编译错误;如果有,执行的是子类重写后方法。如果子类没有重写该方法,就会调用父类的该方法。
总结起来就是:编译看左边,运行看右边。
多态我们首先要知道的一点:
当使用多态方式调用方法时,首先检查父类中是否有该方法,如果没有,则编译错误;如果有,执行的是子类重写后方法。如果子类没有重写该方法,就会调用父类的该方法。
总结起来就是:编译看左边,运行看右边。
首先我们先定义一个父类动物类,动物有吃的行为!
接着定义一个猫类和狗类去继承动物类,重写里面的吃行为!
具体代码如下:
定义动物父类:
package com.nz.pojo;
public class Animal {
public void eat() {
System.out.println("动物它们都会吃东西!!!");
}
}
定义猫咪子类:
package com.nz.pojo;
public class Cat extends Animal{
public void eat() {
System.out.println("小喵咪都喜欢吃鱼罐头!");
}
}
定义小狗子类:
package com.nz.pojo;
public class Dog extends Animal{
public void eat() {
System.out.println("小狗狗都爱啃骨头!");
}
}
定义测试类,测试多态的形式:
package com.nz;
import com.nz.pojo.Animal;
import com.nz.pojo.Cat;
import com.nz.pojo.Dog;
public class Demo {
public static void main(String[] args) {
// 多态形式,创建猫类对象
Animal animal = new Cat();
// 调用的是Cat的 eat
animal.eat();
// 多态形式,创建狗类对象
Animal animal2 = new Dog();
// 调用的是Dog的eat
animal2.eat();
}
}
得到的结果:
小喵咪都喜欢吃鱼罐头! 小狗狗都爱啃骨头!
5. 多态的好处
提高了代码的拓展性,使用父类类型作为方法形式参数,传递子类对象给方法,进行方法的调用。
提高了代码的拓展性,使用父类类型作为方法形式参数,传递子类对象给方法,进行方法的调用。
6. 多态的弊端
- 从上面的多态的好处,可以看到我们可以使用父类的参数代替了某个子类的参数,从而达到程序的扩展!
- 但是对于某个子类有些独有的功能方法时,此时我们的多态的写法就无法访问子类独有功能了。
- 从上面的多态的好处,可以看到我们可以使用父类的参数代替了某个子类的参数,从而达到程序的扩展!
- 但是对于某个子类有些独有的功能方法时,此时我们的多态的写法就无法访问子类独有功能了。
7. 引用类型转换
1. 向上转型(自动转换)
多态本身是子类向父类向上转换(自动转换)的过程,这个过程是默认的。当父类引用指向一个子类对象时,便是向上转型。
对于父类和子类的关系来说,具体来看图说话:
父类相对与子类来说是大范围的类型,Animal是动物类,是父类。
而Cat是猫咪类,是子类。
所以对于父类Animal来说,它的范围是比较大的,它包含一切动物,包括猫咪类和小狗类。
所以对于子类类型这种范围小的,我们可以直接自动转型给父类类型的变量。
- 使用格式:
父类类型 变量名 = new 子类类型(); 如:Animal animal = new Cat(); 相当于有: Animal animal = (Animal) new Cat();
相当于自动帮我们了一个隐形的转换为动物类的一个过程,因为动物本身就包含了猫咪。
2. 向下转型(强制转换)
向下转型就是由父类向子类向下转换的过程,这个过程是强制的。一个需要将父类对象转为子类对象,可以使用强制类型转换的格式,这便是向下转型。
对于父类和子类的关系来说,我们接着看图说话:
- 对于猫咪类的话,它在动物类中只是其中的一部分吧,而对于动物类来说,它有许多其他子类动物如狗,牛,猪等等。
- 所以对于动物父类想要向下转型的时候, 它此时不知道指向那个子类,因为不确定呀,所以就必须自己加上强制的类型转换的一个过程。
使用格式:
子类类型 变量名 = (子类类型) 父类变量名; 如: Animal animal = new Cat(); Cat cat = (Cat) animal; cat.playBall();// 此时我们就可以使用猫咪的特有方法啦
所以对于多态的弊端,无法使用子类特有的参数,我们也解决啦,可以通过向下转型的方法,从而将类型强制转换为某个子类对象后,再去调用子类的特有方法!
3. instanceof关键字
Java为我们提供一个关键字instanceof ,它可以帮助我们避免了ClassCastException 类型转换异常的发生。
Java为我们提供一个关键字instanceof ,它可以帮助我们避免了ClassCastException 类型转换异常的发生。
格式:
变量名 instanceof 数据类型
解释:
如果变量属于该数据类型或者其子类类型,返回true。
如果变量不属于该数据类型或者其子类类型,返回false。
二、链表
1、基础
链表与数组类似,也是一种线性数据结构。
如下图:
链表中的每个元素都是一个对象,每个对象里有一个字段来指向下一个对象元素。
PS:注意,上面的解释中,我并没有说使用指针字段指向下一个对象。在后面图的小节中,会介绍使用数组来模拟链表的方法。
常见的链表有两种类型:单向链表和双向链表。
上面的图片是单向链表,下面的图片是双向链表。
PS:注意,在链表头结点和链表尾节点,有时候会使用指针来标识,有时候会使用额外的对象来标识。
2、复杂度
链表与数组不同,你无法在常量时间内访问单向链表中的随机元素(第几个元素)。
如果你想要获得第i个元素,就必须从头开始遍历。
所以这里按照索引来访问元素的复杂度是O(n)。
3、插入元素
如果你想在链表指定位置之后插入一个元素,则需要这么做。
1.得到待插入节点cur和指定位置节点pre。
2.将cur的next指向pre的next。
3.将pre的next指向cur
可以看到,链表和数组的区别是插入元素时,不需要将之后的所有元素后移。
所以可以在O(1)的复杂度将一个节点插入到指定位置。
4、删除元素
1.找到cur的上一个节点pre。
2.将pre的next指向cur的next即可(cur的next是否删除按具体情况处理)。
如果已经知道pre的话,可以在O(1)复杂度内完成删除。
如果不知道则需要先使用O(n)来找到pre,然后再完成删除。
三、学习心得
单链表还是有点不好理解,额,累累累!!!
单链表还是有点不好理解,额,累累累!!!



