方法重写规则:
- 方法重写的规则方法
- 每一个Java源文件只能有一个公共类,可以有多个非公共类
- 参数列表相同
- 返回值类型相同或者是其子类
- 访问权限不能严于父类
- 父类的静态方法不能被子类覆盖为非静态方法,父类的非静态方法不能被子类覆盖为静态方法
- 子类可以定义与父类同名的静态方法,以便在子类中隐藏父类的静态方法(注:静态方法中无法使用super,也无法使用this,只能用父类名调用如Father.m1())
- 父类的私有方法不能被子类覆盖
- 不能抛出比父类方法更多的异常
Object类:
Object类是所有类的直接或间接父类
Public class Pet extends Object{
……
}
Object类被子类经常重写的方法
方法 |
说明 |
toString() (当前对象的字符串表示) |
返回当前对象本身的有关信息,按字符串对象返回 |
equals() |
比较两个对象是否是同一个对象,是返回true,否返回false |
hashCode() |
返回该对象的哈希代码值 |
getClass() |
获取当前对象所属的类信息,返回Class对象 |
Object类的equals()方法
比较两个对象是否是同一个对象,是返回true,否返回false
操作符==
- 简单数据类型,直接比较值。如1==2
- 引用类型,比较两者是否为同一对象
操作符==和equals()方法的区别
- Object类的equals()方法与==没区别
- 当有特殊需求,如认为属性相同即为同一对象时,需要重写equals()
- Java. lang. String重写了equals()方法,把equals()方法的判断变为了判断其值
默认情况下,equals()作用和 == 是一样的,都是比较两个对象是否为同一个
//重写equals():告诉计算机一个新的比较规则:如果学号和名字都相同,我们认为就是同一个对象
//把传过来的obj对象和this(当前对象)比较
//instanceof操作符的作用:判断某一个对象是否属于某一种类型
public boolean equals(Object obj) {
if(this == obj){
return true;
}
if(!(obj instanceof Student)){
return false;
}
Student s = (Student)obj;
if(this.sid == s.sid && this.name.equals(s.name)){
return true;
}else{
return false;
}
}
public static void main(String[] args) {
Student s1 = new Student(1,"张三",18,50);
Student s2 = new Student(1,"张三",18,50);
//默认情况下,equals()作用和==是一样的,都是比较两个对象是否为同一个
//现实中,如果学号和名字都相同,我们认为即使同一个对象
//Student s2 = s1;
System.out.println(s1 == s2);
System.out.println(s1.equals(s2));
}
toString()方法:
在学生类中重写,显示学生姓名:
toString()方法返回String类型,描述当前对象的有关信息如: Student@1833eca
public String toString() {
return this.name;
}
………
System.out.println(s1.toString());
重载:在同一个类中,方法名相同,参数不同
重写:在子类中,方法名相同,返回值相同,参数相同,访问修饰符要求子类大于等于父类
访问修饰符protected
A Instanceof B 判断A这个类是不是B这个类型的
可以修饰属性和方法
本类、同包、子类
多态:
同一种事物,由于条件不同,产生的结果也不同
多态:同一个引用类型,使用不同的实例而执行不同的操作
呈现多种状态
父类的引用指向了子类的对象,可以调用子类重写父类的方法和父类的方法、属性。
可以直接调用,如:Pet dog = new Dog{………}; Person p = new Student();
方法重写
子类重新写父类的方法 然后调用的时候会调用子类重写的方法 子类重新的参数要和父类的一样
如果没有父类 就直接用基类 public
Java中使用抽象类,限制实例化
抽象类:abstract class,抽象方法不写方法体,为了让子类使用。
(抽象方法没有方法体,有抽象方法的类一定是抽象类,
抽象类不能实例化例如Pet pet = new Pet()就不合法了,
但是可以创建具体的子类对象例如Pet dog = new Dog(………);
抽象类的子类可以使普通类,该普通类要实现抽象类中的抽象方法,
抽象类的子类也可以是抽象类,此时,父类中的抽象方法可以在子类中不被实现)
抽象类里可以写属性、方法、构造方法。
抽象类的构造方法也是为了子类可以重写。
Public abstract class {
……
}
抽象方法:(关键字是abstract,抽象方法没有方法体,抽象方法必须在抽象类中)
抽象方法最后不能加{},用;结尾。
public abstract void toHospital();
向上转型:
父类的引用指向子类对象。自动进行类型转换。
自动转就是向上转
测试方法:
Pet pet = new Dog();
pet.setHealth(20);
Master master = new Master();
master.cure(pet);
注意:
<父类型> <引用变量名> = new <子类型> () ;
此时通过父类引用变量调用的方法是子类覆盖或继承父类的方法(重写以后的方法),不是父类的方法
此时通过父类引用变量无法调用子类特有的方法,只能调用父类子类公有的方法
向下转型:
将一个指向子类对象的父类引用赋给一个子类的引用,即:父类类型转换为子类类型。需强制类型转换
Dog dog=(Dog)pet;//将pet转换为Dog类型
dog. catchingFlyDisc();//执行Dog特有的方法
注意:
<子类型> <引用变量名> = (<子类型>) <父类型的引用变量>;
在向下转型的过程中,如果没有转换为真实的子类类型,会出现类型转换异常(错误类型:java.lang.ClassCastException)
Instanceof:
如何减少在向下转型的过程中,没有转换为真实子类类型的类型转换异常?
Java中提供了instanceof运算符来进行类型的判断
注意:
使用instanceof时,对象的类型必须和instanceof后面的参数所指定的类在继承上有上下级关系
使用父类作为方法的形参,是Java中实现和使用多态的主要方式
使用父类作为方法的返回值,也是Java中实现和使用多态的主要方式
简单工厂(Simple Factory):设计模式中的一种
简单工厂的成员有: 工厂类 抽象产品类 具体产品类 客户
一个工厂类,根据客户传入的具体参数,决定生产哪种具体产品。但是返回时客户看到是抽象的类型,但是获得到的是具体的产品。
绑定机制:静态绑定 动态绑定
实例方法:调用的时候遵循动态绑定机制,与引用变量实际引用的对象绑定,调用重写后的方法,由运行时的jvm决定
静态方法:调用的时候遵循静态绑定机制,与引用变量所声明的类型绑定,实际上在编译阶段就做了绑定
成员变量:包括静态变量和实例变量,与引用变量所声明的类型绑定,实际上在编译阶段就做了绑定,实际上也是一种静态绑定