目录
例如:手机分为智能机和老人机,老人机得按键拨号,而智能机可以语言控制拨号
方法重写:子类需要重写父类中的方法,即在子类中提供一个具有相同方法名、参数列表和返回类型的新实现。
接口实现:接口也可以实现多态,当一个类实现了一个或多个接口,并提供了接口中声明的方法的具体实现时,可以通过接口引用调用实现类的方法。
抽象类和抽象方法:抽象类不能被实例化,但可以作为其他类的基类,抽象方法必须在子类中被重写。
方法重写:子类重写父类的方法时,方法名、参数列表和返回类型必须与父类中的方法完全一致。
子类Pig,继承Animal,并且对Animal中eat()方法进行重写
一、多态的定义以及存在条件
1.1 多态的定义
多态是什么?
- 多态是同一个行为具有不同的表现形式或形态的能力
- 同一方法可以根据发送对象的不同而采用不同的行为方式
例如:手机分为智能机和老人机,老人机得按键拨号,而智能机可以语言控制拨号
多态就是多种形态,对象在不同条件下表现出不同形式
1.2 多态的存在条件
继承:多态性要求存在继承关系,即子类继承父类。
方法重写:子类需要重写父类中的方法,即在子类中提供一个具有相同方法名、参数列表和返回类型的新实现。
接口实现:接口也可以实现多态,当一个类实现了一个或多个接口,并提供了接口中声明的方法的具体实现时,可以通过接口引用调用实现类的方法。
抽象类和抽象方法:抽象类不能被实例化,但可以作为其他类的基类,抽象方法必须在子类中被重写。
1.3 多态的格式
方法重写:子类重写父类的方法时,方法名、参数列表和返回类型必须与父类中的方法完全一致。
class Parent {
void show() {
System.out.println("Parent's show()");
}
}
class Child extends Parent {
@Override
void show() {
System.out.println("Child's show()");
}
}
向上转型:将子类对象赋值给父类引用,这是实现多态的基础。
Parent p = new Child();
p.show(); // 调用子类重写的方法
- 父类类型 变量名 = new 子类类型();
代码中:Parent p = new Child();- 然后通过 变量名.方法名()调用在子类中重写的方法
代码中:p.show();
1.4 多态中成员特点
多态成员变量
父类Animal
public class Animal {
String name = "动物";
}
子类Pig,继承Animal
public class Pig extends Animal{
String name = "猪";
}
测试类:
public class Test {
public static void main(String[] args) {
Animal pig = new Pig();
System.out.println(pig.name);
}
}
输出结果为:动物
解释:Pig的引用类型是Animal,Pig是属于Animal类,Animal中变量的值是多少就通过对象就取得多少
多态成员方法
父类Animal
public class Animal {
public void eat(){
System.out.println("动物吃饭");
}
}
子类Pig,继承Animal,并且对Animal中eat()方法进行重写
public class Pig extends Animal{
@Override
public void eat(){
System.out.println("猪吃饭");
}
}
测试类:
public class Test {
public static void main(String[] args) {
Animal pig = new Pig();
pig.eat();
}
}
输出结果为:猪吃饭
Animal 为引用类型,pig为实际类型为Pig,pig.eat();调用的是重写之后的
1.5 多态特点
- 多态情况下,子类和父类存在同名的成员变量时,访问的时父类的成员变量
- 多态情况下,子父类存在同名的非静态成员方法时,访问的是子类中重写的方法
- 多态情况下,子父类存在同名的静态成员变量成员方法时,访问的是父类的成员函数
- 多态情况下,不能访问子类独由的方法
父类Animal
public class Animal {
public void eat(){
System.out.println("动物吃饭");
}
public void run(){
System.out.println("动物奔跑");
}
}
子类Pig
public class Pig extends Animal{
public void play(){
System.out.println("猪在玩");
}
@Override
public void eat(){
System.out.println("猪吃饭");
}
}
测试类:
public class Test {
public static void main(String[] args) {
Animal pig = new Pig();
pig.eat();
pig.run();
pig.play();
}
}
我们在调用子类独有的方法是会发现爆红
所以对于子类独有的方法,父类无法访问。
1.6 练习
创建了A、B、C、D四个类
public class A {
public String show(D obj) {
return ("A and D");
}
public String show(A obj) {
return ("A and A");
}
}
B继承A
public class B extends A{
public String show(B obj){
return ("B and B");
}
public String show(A obj){
return ("B and A");
}
}
C继承B
public class C extends B{
}
D继承B
public class D extends B{
}
请写出下面代码的运行结果
public class Test {
public static void main(String[] args) {
A a1 = new A();
A a2 = new B();
B b = new B();
C c = new C();
D d = new D();
System.out.println("1--" + a1.show(b));
System.out.println("2--" + a1.show(c));
System.out.println("3--" + a1.show(d));
System.out.println("4--" + a2.show(b));
System.out.println("5--" + a2.show(c));
System.out.println("6--" + a2.show(d));
System.out.println("7--" + b.show(b));
System.out.println("8--" + b.show(c));
System.out.println("9--" + b.show(d));
}
}
答案:
- A and A
- A and A
- A and D
- B and A
- B and A
- A and D
- B and A
- B and A
- A and D