基本概念
多态是同一个行为具有多个不同表现形式或形态的能力。
多态性是对象多种表现形式的体现。
多态发生的条件 :继承、重写、向上转型
动态绑定是多态实现的具体形式。
实例探究
下面通过一个例子验证上面的概念。
// 车
class Car {
public void show(){
System.out.println("This is a car");
}
}
//丰田
class Toyota extends Car{
public void show(){
System.out.println("This is a Japan car");
}
}
//别克
class Buick extends Car{
public void show(){
System.out.println("This is a USA car");
}
}
public class Test{
public static void main(String[] args) {
Car c1 = new Toyota();
Car c2 = new Buick();
c1.show();
c2.show();
// 打印内容:
// This is a Japan car
// This is a USA car
}
}
观察代码,在调用 Car 的 show 方法时打印了不同的内容,体现了类的多态性。同时例子也满足了发生多态的三个基本条件:
- 继承:Toyota 、Buick 继承自 Car
- 重写: Toyota 、Buick 重写了 Car 的 show 方法
- 向上转型:创建 Toyota 、Buick 对象时发生向上转型
再来看来一个典型题目:
class A {
public String show(A obj) {
return ("A and A");
}
public String show(D obj) {
return ("A and D");
}
}
class B extends A {
public String show(A obj) {
return ("B and A");
}
public String show(B obj) {
return ("B and B");
}
}
class C extends B {
}
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();
// 1.因此 B 是 A 的子类,调用类 A 的 show(A obj) 方法,输出:A and A
System.out.println(a1.show(b));
// 2.因为 C 是 A 的子类,调用类 A 的 show(A obj) 方法,输出:A and A
System.out.println(a1.show(c));
// 3.调用类 A 的 show(D obj) 方法,输出:A and D
System.out.println(a1.show(d));
// 4.因为 B 向上转型成 A, 且 B 是 A 的子类,调用类 A 的 show(A obj) 方法
// 但是由于 B 中重写了 show(A obj) 方法,导致运行期间发生的动态绑定,调用 类 B 的 show(A obj) 方法
// ,输出:B and A
System.out.println(a2.show(b));
// 5.同上
System.out.println(a2.show(c));
// 6.B 向上转型成 A,默认调用类 A 的 show(D obj) 方法,输出:A and D
System.out.println(a2.show(d));
// 7.调用类 B 的 show(B obj) 方法,输出:B and B
System.out.println(b.show(b));
// 8.C 是 B 的子类,调用类 B 的 show(B obj) 方法,输出:B and B
System.out.println(b.show(c));
// 9.调用继承自类 A 的 show(D obj) 方法,输出:A and D
System.out.println(b.show(d));
}
}
构造器与多态
同样的通过一个实例来探究
class Parent {
void print() {
System.out.println("I am a Parent");
}
Parent() {
print();
}
}
class Son extends Parent {
int num = 1;
// 重写(override)了父类方法
void print() {
System.out.println("I am a Son " + num);
}
Son() {
print();
}
}
public class Test {
public static void main(String[] args) {
Son son = new Son();
/**
* 输出内容:
* I am a Son 0
* I am a Son 1
*/
}
}
通过输出内容我们可以看到,Parent 的构造器由于动态绑定,调用了 Son 的 print(),由于 num 还未被初始化,导致了值为 0。
基本概念
多态是同一个行为具有多个不同表现形式或形态的能力。
多态性是对象多种表现形式的体现。
多态发生的条件 :继承、重写、向上转型
动态绑定是多态实现的具体形式。
实例探究
下面通过一个例子验证上面的概念。
// 车
class Car {
public void show(){
System.out.println("This is a car");
}
}
//丰田
class Toyota extends Car{
public void show(){
System.out.println("This is a Japan car");
}
}
//别克
class Buick extends Car{
public void show(){
System.out.println("This is a USA car");
}
}
public class Test{
public static void main(String[] args) {
Car c1 = new Toyota();
Car c2 = new Buick();
c1.show();
c2.show();
// 打印内容:
// This is a Japan car
// This is a USA car
}
}
观察代码,在调用 Car 的 show 方法时打印了不同的内容,体现了类的多态性。同时例子也满足了发生多态的三个基本条件:
- 继承:Toyota 、Buick 继承自 Car
- 重写: Toyota 、Buick 重写了 Car 的 show 方法
- 向上转型:创建 Toyota 、Buick 对象时发生向上转型
再来看来一个典型题目:
class A {
public String show(A obj) {
return ("A and A");
}
public String show(D obj) {
return ("A and D");
}
}
class B extends A {
public String show(A obj) {
return ("B and A");
}
public String show(B obj) {
return ("B and B");
}
}
class C extends B {
}
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();
// 1.因此 B 是 A 的子类,调用类 A 的 show(A obj) 方法,输出:A and A
System.out.println(a1.show(b));
// 2.因为 C 是 A 的子类,调用类 A 的 show(A obj) 方法,输出:A and A
System.out.println(a1.show(c));
// 3.调用类 A 的 show(D obj) 方法,输出:A and D
System.out.println(a1.show(d));
// 4.因为 B 向上转型成 A,应该是调用类 A 的 show(A obj) 方法
// 由于 B 中重写了 show(A obj) 方法,实际调用 类 B 的方法,,输出:B and A
System.out.println(a2.show(b));
// 5.同上
System.out.println(a2.show(c));
// 6.B 向上转型成 A,默认调用类 A 的 show(D obj) 方法,输出:A and D
System.out.println(a2.show(d));
// 7.调用类 B 的 show(B obj) 方法,输出:B and B
System.out.println(b.show(b));
// 8.C 是 B 的子类,调用类 B 的 show(B obj) 方法,输出:B and B
System.out.println(b.show(c));
// 9.调用继承自类 A 的 show(D obj) 方法,输出:A and D
System.out.println(b.show(d));
}
}
构造器与多态
同样的通过一个实例来探究
class Parent {
void print() {
System.out.println("I am a Parent");
}
Parent() {
print();
}
}
class Son extends Parent {
int num = 1;
// 关键 -> 重写了父类的方法
void print() {
System.out.println("I am a Son " + num);
}
Son() {
print();
}
}
public class Test {
public static void main(String[] args) {
Son son = new Son();
// 输出内容:
// I am a Son 0
// I am a Son 1
}
}
分析结果,其实它涉及到了三个内容:
- Son 在实例化的过程中,Parent 的构造函数, Parent 的构造函数先执行。
- Son 重写了 print 方法,因此 Parent 调用的是 Son 重写后的方法。
- 在 Parent 由于 num 还未被初始化,因此值为 0。