Java多态理解

一句话概括就是:事物在运行过程中存在不同的状态。

多态的三个前提:

1、要有继承关系;

2、子类要重写父类的方法;

3、父类引用指向子类对象。

但是其中又有很多细节需要注意。首先我们定义两个类,一个父类Animal,一个子类Cat。

父类Animal

class Animal {
	int num = 10;
	static int age = 20;
 
	public void eat() {
		System.out.println("动物吃饭");
	}
 
	public static void sleep() {
		System.out.println("动物在睡觉");
	}
 
	public void run() {
		System.out.println("动物在奔跑");
	}
}

子类Cat

class Cat extends Animal {
	int num = 80;
	static int age = 90;
	String name = "tomCat";
 
	public void eat() {
		System.out.println("猫吃饭");
	}
 
	public static void sleep() {
		System.out.println("猫在睡觉");
	}
 
	public void catchMouse() {
		System.out.println("猫在抓老鼠");
	}
}

测试类Test

class Test {
	public static void main(String[] args) {
		Animal am = new Cat();
 
		am.eat();
		am.sleep();
		am.run();
		//am.catchMouse();这里先注释掉,等会会说明
		//System.out.println(am.name);//这里先注释,待会说明
		System.out.println(am.num);
		System.out.println(am.age);
	}
}

那我们来看一下运行结果:

可以看出来

子类Cat重写了父类Animal的非静态成员方法am.eat();的输出结果为:猫吃饭

子类重写了父类(Animal)的静态成员方法am.sleep();的输出结果为:动物在睡觉

未被子类(Cat)重写的父类(Animal)方法am.run()输出结果为:动物在奔跑

System.out.println(animal.num);//输出结果为10
System.out.println(animal.age);//输出结果为20

那么我们可以根据以上情况总结出多态成员访问的特点:

成员变量:编译看左边(父类),运行看左边(父类)

成员方法:编译看左边(父类),运行看右边(子类)。动态绑定

静态方法:编译看左边(父类),运行看左边(父类)。 (静态和类相关,算不上重写,所以,访问还是左边的)

只有非静态的成员方法,编译看左边,运行看右边

此外,以上的三段代码充分体现了多态的三个前提:

1、存在继承关系

Cat类继承了Animal类 .

2、子类要重写父类的方法

子类重写(override)了父类的两个成员方法eat(),sleep()。其中eat()是非静态的,sleep()是静态的(static)。

3、父类引用指向子类对象

测试类Test中 Animal am = new Cat();语句在堆内存中开辟了子类(Cat)的对象,并把栈内存中的父类(Animal)的引用指向了这个Cat对象。

到此,满足了Java多态的的必要三个前提。

 

多态的弊端

那么多态有什么弊端呢?有的,即多态不能使用子类特有的属性和方法。往上面代码看,子类Cat有一个特有的属性String name="tomCat";并且还有一个特有的抓老鼠的方法catchMouse()。但是在测试类(Demo_Test)中,我们尝试调用子类特有的方法catchMouse()和打印子类特有的成功属性String name="tomCat";就会报错。
 

am.catchMouse();
System.out.println(am.name);

原因就是多态的弊端,就是:不能使用子类特有的成员属性和子类特有的成员方法

 

如果在代码执行过程中还想使用Cat类特有的属性String name和它持有的成员方法catchMouse()了怎么办呢?那我们就可以把这个父类引用指向了子类对象的家伙am再强制变回Cat类型。这样am就是Cat类型的引用了,指向的也是Cat对象了,自然也能使用Cat类的一切属性和一切的成员方法

class Test {
	public static void main(String[] args) {
		Animal am = new Cat();
 
		am.eat();
		am.sleep();
		am.run();
		//am.catchMouse();这里先注释掉,等会会说明
		//System.out.println(am.name);//这里先注释,待会说明
		System.out.println(am.num);
		System.out.println(am.age);

        Sytem.out.println("------------------------");
        Cat ct = (Cat)am;
        ct.eat();
        ct.sleep();
        ct.run();
        ct.catchMouse();
	}
}

 

Animal am = new Cat();   //多态中的向上转型

Cat ct = (Cat)am;             //多态中的向下转型

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值