p303-326
和重载做个对比
注:但子类可以扩大范围,比如父类是protected,子类可以是public
方法或对象具有多种形态,是面向对象的第三大特征,多态是建立在封装和继承基础之上的。
多态的具体体现:
1.方法重载体现多态
通过不同的参数个数去调用sum方法,就会调用不同的方法,因此对sum方法来说,就是多种状态的体现。
2.方法重写体现多态
3.对象的多态(核心)
(1)一个对象的编译类型和运行类型可以不一致
(2)编译类型在定义对象时,就确定了,不能改
(3)运行类型是可以变的
(4)编译类型看定义时 = 号的左边,运行类型看 = 号右边。
例:Animal a1 = new Dog();//a1的编译类型是Animal,运行类型是Dog,
a1 = new Cat();//a1的运行类型变成了Cat,编译类型仍然是Animal
多态,一定是建立在封装和继承之上的,向上转型:父类的引用,指向了子类对象,如:
Animal a1 = new Dog();就是向上转型
可以调用父类的所有成员(考虑访问权限)
不能调用子类特有成员,最终运行效果看子类的具体实现,也就是说只能调用子类重写的方法
Dog d1 = (Dog)a1;
1.只能强转父类的引用,不能强转父类的对象!
2.要求父类的引用必须指向的是当前目标类型(比如猫不能转成狗,但是动物(指向狗的)可以转成狗)
3.向下转型后可以调用子类类型中所有成员。
我可以理解为,向下转型的前提是向上转型吗?
注意:属性没有重写一说!
属性的值看编译类型,方法看运行
instanceof比较操作符,用于判断对象的运行类型
1.当调用对象方法的时候,该方法会和该对象的内存地址/运行类型绑定
2.当调用对象属性时,没有动态绑定机制,哪里声明,哪里使用
0314_韩顺平Java_动态绑定机制_哔哩哔哩_bilibili
数组的定义类型为父类类型,里面保存的实际元素类型为子类类型
练习:创建一个Person对象,2个Student对象,和2个Teacher对象,统一放在数组中,并调用say方法。
升级后:
弄了个新的引用指向people【1】。这里有个teacher类
向下转型的快捷写法:
(Student)people[i].study();
方法定义的形参类型为父类类型,实参类型允许为子类类型。
0317_韩顺平Java_多态参数_哔哩哔哩_bilibili
1==:既可以判断基本类型,又可以判断引用类型
2基本类型判断“值”。
3引用类型判断“地址”,即判断它们是不是同一个对象。
4equals是Object类的方法,只能用来判断引用类型
例:String的equals的源码:
如果传进来的对象就是当前对象,返回t。
如果传进来的是字符串(及其子类),那么向下转型(为什么不是向上??),接下来判断长度,并逐个字符比较。
如果比较的不是字符串,则直接返回f。
那么最原始的equals呢?↓
所以Object的equals方法默认就是比较对象的地址是否相同,即是不是同一个对象。
这里String中的equals把Object的equals重写了。
例2:
第一个是==,判断地址是否相同,返回false,因为这里有两个对象
第二个equals已经被int类重写了,int类的equals源码是
即比较它们的值,因此返回true
自己重写equals
public class Person{
private int age;
private String name;
private char gender;
public boolean equals(Object obj){
if(this == obj){
return true;}
if(obj instanceof Person){
Person p = (Person)obj;
return this.name.equals(p.name)&&this.age == p.age&&this.gender==p.gender;
}return false;
}
}
课堂练习:
F T F T F
F T,这里65和65.0的值是一样的
T
T
F
T
没见过不知道:Date是一个类型,“hello”是字符串,直接编译器报错
返回对象的哈希码值,为了提高哈希表的性能。(哈希表是啥捏?听说后面会讲)
老韩的6个结论:
1.提高具有哈希结构的容器的效率
2.两个引用,如果指向的是同一个对象,则哈希值肯定是一样的
3.两个引用,如果指向的是不同对象, 当然哈希值也不一样
4.哈希值主要根据地址号来的,不能完全将哈希值等价于地址
5.后面再集合中hashCode如果需要的话,也会重写
源码:
就是把对象的hashCode值转换为16进制的字符串~
经常会重写toString方法,输出对象的属性,甚至有模板。
当输出一个对象时,toString方法会被默认调用: