1、重写(Override)
即字面意思,将方法重新写一遍,指的是在子类中把父类的本身有的方法重新写一遍
注意:在方法名,参数列表,返回类型(除过子类中方法的返回值是父类中方法返回值的子类时)都相同的情况下,对方法体进行修改或重写,这就是重写
2、重载(Overload)
指的是 在一个类中,同名的方法如果有不同的参数列表(参数类型不同、参数个数不同甚至是参数顺>.序不同)则视为重载。同时,重载对返回类型没有要求,可以相同也可以不同,但不能通过返回类型是否相同来判断重载。
3、如何实现多态
实现多态有三个必要条件:继承、重写、向上转型
(1) 继承:在多态中必须存在有继承关系的子类和父类。
(2) 重写:子类对父类中某些方法进行重新定义,在调用这些方法时就会调用子类的方法。
(3) 向上转型:在多态中需要将子类的引用赋给父类对象,只有这样该引用才能够具备技能调用父类的方法和子类的方法。
4、向上转型
父类的引用变量去指向子类的实例对象,当向上转型之后,父类引用变量可以访问子类中属于父类的属性和方法,但是不能访问子类独有的属性和方法。
模板: 父类类名 引用变量=new 子类();
5、向下转型
在实例化对象时,当一个父类引用指向的是的子类对象, 此时创建此子类的一个引用,通过强制转换的方式,可以将父类引用赋给子类引用。
模板: 父类类名 引用变量1=new 子类类名(); 子类类名 引用变量2=(子类类名)引用变量1;
栗子:
class People{
String name;
String ID;
public People(String name,String ID){
this.name=name;
this.ID=ID;
}
public void drink(String name,String ID){
System.out.println(this.name+"喝水啊");
}
public void drink(String ID){
System.out.println(this.ID+"喝水");
}
}
class Teacher extends People{
public Teacher(String name, String ID) {
super(name, ID);
}
public void drink(String name,String ID){
System.out.println(this.name+"喝茶水啊");
}
public void drink(String ID){
System.out.println(this.ID+"喝茶");
}
public void eat(String ID){
System.out.println(this.ID+"喜欢吃油泼面");
}
}
class Stu extends Teacher{
public Stu(String name, String ID) {
super(name, ID);
}
public void drink(String name, String ID){
System.out.println(this.name+"喝可乐啊");
}
public void drink(String ID){
System.out.println(this.ID+"喝可乐");
}
}
public class Main {
public static void main(String[] args) {
People p=new Teacher("徐老师","001");//向上转型
/**
* 向上转型:父类的引用变量去指向子类的实例
* 当向上转型之后,父类引用变量可以访问子类中属于父类的属性和方法,
* 但是不能访问子类独有的属性和方法。
*/
p.drink(p.name,p.ID);
p.drink(p.ID);
// p.eat(p.ID);//报错,父类引用不能够调用子类特有的方法
/**
* 徐老师喝茶水啊
* 001喝水
*/
System.out.println("==============");
People people=new Stu("徐同学","Stu001");
people.drink(people.ID);
people.drink(p.ID);
/** p.ID=001,但是this依然指向的是对象people-->Stu("徐同学","Stu001");
*所以this.ID依然是Stu001,
*所以输出的是:Stu001喝可乐
*/
p.drink(people.ID);
/**
* people.ID=Stu001;但是this依然指向的是对象是p-->new Teacher("徐老师","001");
* 所以this.ID依然是001
* 输出:001喝茶
*/
System.out.println(p.ID);
System.out.println(people.ID);
System.out.println(p.ID.equals(people.ID));
System.out.println(people.equals(p));
/**
* Stu001喝可乐
* Stu001喝可乐
* 001喝茶
* 001
* Stu001
* false
* false
*
* Process finished with exit code 0
*/
System.out.println("==============");
// //Stu stu=new People("张同学","Stu002");//错误,子类引用不能指向父类对象
// People people1=new People("张同学","Stu002");
//
// Stu stu1=(Stu) people1;//此处的向下转型失败
// /**
// * 编译正确,编译时报错
// * Exception in thread "main" java.lang.ClassCastException:
// * 复习.重载与重写.People cannot be cast to 复习.重载与重写.Stu
// */
// stu1.drink(stu1.ID);
// Stu stu= (Stu) new People("张同学","Stu002");//需要强制类型转换
// /**
// * 编译正确,编译时报错
// * Exception in thread "main" java.lang.ClassCastException:
// * 复习.重载与重写.People cannot be cast to 复习.重载与重写.Stu
// */
// stu.drink(stu.ID);
// /**
// * 由于上方编译时报错,不会执行到这里
// */
Stu stu=new Stu("小徐","Stu003");//子类对象实例化
stu.eat(stu.ID);//子类引用可以调用父类的方法
/**
*输出:
* Stu003喜欢吃油泼面
*/
System.out.println("==============");
/**
* 向下转型:
* 在实例化对象时,当一个父类引用指向的是的子类对象:
* 即:父类类名 引用变量1=new 子类类名();
* 此时创建此子类的引用,通过强制转换,可以将父类引用赋给子类:
* 即:子类类名 引用变量2=(子类类名)引用变量1
*/
People person=new Stu("衡仔","Stu004");
Stu stu1=(Stu)person;
stu1.drink(stu1.ID);
/**
* Stu004喝可乐
*/
}
}