往往在继承的子类与父类中存在大量的冗余代码,这时候我们就需要用到重写来减少代码的行数,方便查看。
方法重写:有以下几个关键地方
要实现重写我们需要:要有继承关系
子类与父类有同名方法
1.方法名相同
2.参数列表相同
3.返回值类型相同,或者是父类返回值类型的子类
4.访问修饰符的权限不能小于父类方法
5.抛出的异常不能多于父类(严于)
示例:
public class Cat extends Pet{
//private私有化,保护属性不被篡改
public Cat(){
}
public Cat(String name, int health, int love,String strain,String sex) {
super(name, health, love,strain,sex);
}
我们的cat子类继承父类Pet
public class Pet extends Object{
private String name;
private int health;
private int love;
private String strain;
(。。。。。。。。。setter/getter)
public void show(){
System.out.println("宠物的自白:");
System.out.println("我叫"+name+",健康值是:"+health+",和主人的亲密度:"+
love);
}
在父类Pet方法中存在show方法
此时我们在子类cat中重写父类pet方法
public void show(){
super.show();
System.out.println("我的性别是:"+getSex());
}
这里我们用到了super.方法去调用父类的方法,然后继续编写属于cat类的代码来实现重写。
在重写的基础上,java的另一大特性多态产生。
多态:同一个引用类型,使用不同的实例而执行不同操作
示例:Dog类
public class Dog extends Pet {
public void toHospital() {
this.setHealth(60);
System.out.println("打针、吃药");
}}
Penguin类
public class Penguin extends Pet {
public void toHospital() {
this.setHealth(70);
System.out.println("吃药、疗养");
}}
主人类
public class Master {
public void cure(Pet pet) {
if (pet.getHealth() < 50)
pet.toHospital();
}}
测试类:
Pet pet = new Dog();
Master master = new Master();
master.cure(pet);
通过父类引用子类方法的形式形成多态-,从而执行不同类里面的重写后的方法。
通过多态形式,我们不需要在父类里面具体写方法体,因为所有的逻辑都可以在子类中进行重写。
在这种情况下就出现了一个定义:抽象类,抽象方法。
抽象类:抽象方法没有方法体
抽象方法必须在抽象类里
抽象方法必须在子类中被实现,除非子类是抽象类
在这里定义一个抽象方法
public abstract class Pet {
private String name;
private int health;
private int love;
public abstract void eat();
public abstract void play();
其中有eat,play的抽象方法。
此时cat类继承pet方法。
public class Cat extends Pet {
public void toHospital() {
if (getHealth() < 50) {
setHealth(90);
System.out.println("猫有九条命,不用救");
}
}
public Cat() {
}
public Cat(String name, int health, int love) {
super(name, health, love);
}
@Override
public void eat() {
if (getHealth() == 100)
System.out.println("饱了,不吃");
else {
System.out.println( "猫吃了鱼");
if (getHealth() + 5 > 100) {
setHealth(100);
} else {
setHealth(getHealth() + 5);
}
}
}
@Override
public void play() {
}
可以看到,只要一个类继承了一个抽象类,这个抽象类里面的抽象方法,需要全部进行重写,不然子类就会报错。
除非这个子类也是抽象方法。
注意:比须全部重写,而且是所有抽象方法,就算你没有用到这个方法,也需要重写,只不过你可以不写方法体
此外,抽象类不能被实例化
也就是在测试类中不能进行
Pet p =new Pet();
此时我们可以使用多态去进行操作。这里就产生了所谓的向上转型和向下转型。
向上转型:这里我们使用常使用的一种所谓的代理模式
在返回值中使用多态
public static final String CAT = "cat";
public static final String DOG = "dog";
public static final String PENGUIN = "penguin";
public Pet getPet(String type) {
Pet p = null;
if (CAT.equals(type)) {
p = new Cat();
}
if (DOG.equals(type)) {
p = new Dog();
}
if (PENGUIN.equals(type)) {
p = new Penguin();
}
return p;
}
Pet类型的直接转化为cat,dog,penguin 类型
向下转型:
Scanner input = new Scanner(System.in);
Master m = new Master();
System.out.print("输入要领养的宠物类型:");
Pet p = m.getPet(input.next());
if (p instanceof Cat)
{
Cat c = (Cat) p;
}
if (p instanceof Dog) {
Dog d = (Dog) p;
}
if (p instanceof Penguin) {
Penguin penguin = (Penguin) p;
}
if (p instanceof Fish) {
Fish fish = (Fish) p;
}
此时Pet类类似于变量的强转,需要强制转换,这就是向下转型
其中我们看到一个 instanceof 关键字
他的作用是进行类型的判断:如果类型相同则返回true,反之则返回false
注意:使用instanceof时,对象的类型必须和instanceof后面的参数所指定的类在继承上有上下级关系