java—方法重写和多态
一、方法重写
子类继承父类之后,每个子类中的具体方法都会不一样,如果每次都要在子类中新定义一个方法,会很繁琐。因此,在父类中写一个空方法体,而在子类中对此方法进行重写。
父类方法:pet类的eat方法
public abstract void eat();
或者
pubic void eat(){
};
子类进行方法重写: Dog类的eat方法
public void eat(){
do {
if(this.getHealth()<100) {
System.out.println("我是狗狗,需要吃骨头,吃完健康值增加20");
this.setHealth(this.getHealth() + 20);
}else {
System.out.println("我吃饱了!");
break;
}
}while(this.getHealth()<100);
}
子类进行方法重写: Penguin类的eat方法
public void eat(){
System.out.println("我是企鹅,需要吃鱼,吃完健康值增加30");
}
如果在测试类中
Pet pet1 = new Dog(); //向上转型
Pet pet2 = new Penguin();
pet1.eat()//自动调用Dog类的eat方法
pet2.eat()//自动调用Penguin类的eat方法
重写方法之后,方法作则会有overrides的标记
如果是在抽象类中实现抽象类方法,方法左侧会有Implements的标记:
二、方法重写的规则
主要的规则:
1、父类的方法与子类的方法同名
2、返回值类型相同或者子类的类型是父类返回值类型的子类
3、参数列表相同
4、访问修饰符不能比父类范围来的小
细一点的规则
三、方法重写和重载的区别
方法的重载是可以在不同类的,比如子类的继承父类的某个方法,而子类将这个方法进行重载,也算是方法的重载。
四、Object类
重写toString方法
System.out.println()其实调用Object toString()方法
重写Object 中的toString方法可以:
1、隐藏某个对象的地址
2、打印类的属性名称,开发过程中的一些常用手段
自定义equals方法
自定义equals方法和重写Object的equals方法的区别
public boolean equals(Student s){
//自定义equals方法
if(null==s.name||s.number!=this.number) return false;
if(this.getName().equals(s.name)&&this.getNumber()==s.number) {
return true;}
return false;
}
@Override
public boolean equals(Object obj) {
//重写Object的equals方法`在这里插入代码片`
return super.equals(obj);
}
两个特殊例子:
d1和d2是两个Dog类对象
System.out.println(d1) //地址
System.out.println(d1) //地址
System.out.println(d1==d2) //false ,比较两个对象的地址
String s1 = "abc";
String s2 = "abc";
String s3 = new String ("abc");
String s4 = new String ("abc");
System.out.println(s1==s2) //true 两个常量池中的变量比较,数值
System.out.println(s2==s3) //false new对象之后,开辟空间之后,地址就不一样了
System.out.println(s3==s4) //false 同上
五、多态(方法重写是实现多态的基础)
多态的使用1
Mater类
public void cure(Pet pet){
//主人不知道pet到底是哪个一个类型
pet.toHospital();
}
Penguin类:
public void toHospital(){
"父类去医院"; //如果子类没有重写方法,就使用父类的toHospital()方法;
}
Dog类:
public void toHospital(){
System.out.println("我是狗狗,我不想去医院!")
}
Penguin类:
public void toHospital(){
System.out.println("我是企鹅,我也不想去医院!")
}
测试类:
Master master = new Master();
Dog d = new Dog();
Penguin p = new Penguin();
master.cure(d);//调用Dog类的tohospital方法
master.cure(p);//调用Penguin类的tohospital方法
多态的使用2
子类对象引用父类类型
Pet pet = new Dog();
父类被重写的方法被抽象化
public abstract void toHospital();
public abstract class Pet(){
}//对应的类也要被写成抽象类
继承了抽象类的子类,必须实现父类中的 抽象方法:
抽象类不可以实例化(除非用匿名内部内的方法,相当于创建了一个子类,但是没用命名)
多态的使用3
Cat类有个独特的方法:
public class Cat extends Pet{
public void climb(){
System.out.println("爬树!");
}
}
而父类Pet类中没有climb方法,那么在向上转型的情况下,无法调用cat类的特有方法,需要向下转型
Pet c = new Cat();
((cat) c ).climb();
同时为了保证转型的安全,需要instanceof 进行校验
if(c instanceof Cat)(确保转型的精确性)
向下转型的另一种使用:
父类类型作为返回值类型时,需要对返回值类型进行判断