1、形成多态的条件
1、继承
2、重写
3、父类引用指向子类对象
2、在多态的情形之下成员的访问特点:
成员属性:编译器,主看父类 (父类存在,编译)运行也看父类
成员方法:主看父类 (父类存在,编译),运行看子类
public class T {
public static void main(String[] args) {
A a=new B(); //多态形成条件 3:父类引用指向子类对象
a.say();
System.out.println(a.x);
}
}
class A{
int x=1;
void say() {
System.out.println("A");
}
}
class B extends A{ //多态形成条件 1:继承
int x=2; //
void say() { //多态形成条件 2: 重写
System.out.println("B");
}
}
运行结果: B
1
注意:多态的弊端:不能访问子类特有的成员属性和成员方法:
public class T {
public static void main(String[] args) {
A a=new B();
a.say();
a.say("错误"); // 程序报错
System.out.println(a.x);
}
}
class A{
int x=1;
void say() {
System.out.println("A");
}
}
class B extends A{
int x=2;
void say() {
System.out.println("B");
}
void say(String s) {
System.out.println("B"+s);
}
}
3、多态的应用:参数是父类,但传入的是子类
首先来看没有用多态的情况:
public class Test {
public static void main(String[] args) {
Circus circus = new Circus();
Cat cat = new Cat();
circus.program(cat);
Dog dog = new Dog();
circus.program(dog);
Pig pig = new Pig();
circus.program(pig);
}
}
class Circus {
void program(Cat c) {
c.play();
}
void program(Dog d) {
d.play();
}
void program(Pig p) {
p.play();
}
//。。。每次新增节目都要新增重载方法
}
abstract class Animal {
abstract void play();
}
class Dog extends Animal {
void play() {
System.out.println("狗吃骨头");
}
}
class Cat extends Animal {
void play() {
System.out.println("猫吃鱼");
}
}
class Pig extends Animal {
void play() {
System.out.println("猪上树");
}
}
再来看使用多态的情况:
public class Test {
public static void main(String[] args) {
Circus circus = new Circus();
Animal a=new Cat();
circus.program(a);
Animal d=new Dog();
circus.program(d);
Animal p=new Pig();
circus.program(p);
}
}
class Circus {
void program(Animal a) { //只要写一个方法就好了
a.play();
}
}
abstract class Animal {
abstract void play();
}
class Dog extends Animal {
void play() {
System.out.println("狗吃骨头");
}
}
class Cat extends Animal {
void play() {
System.out.println("猫吃鱼");
}
}
class Pig extends Animal {
void play() {
System.out.println("猪上树");
}
}
4、多态的另一种用法:向下转型
向下转型用于调用子类特有成员:
package com.package3_8.extend;
public class T {
public static void main(String[] args) {
A a=new B();
a.say();
B b=(B)a; //向下转型
b.say("正确"); //调用子类特有方法
System.out.println(a.x);
}
}
class A{
int x=1;
void say() {
System.out.println("A");
}
}
class B extends A{
int x=2;
void say() {
System.out.println("B");
}
void say(String s) {
System.out.println("B"+s);
}
}