本文思路:
多态概念:某一个事物,在不同时刻表现出来的不同状态。
(1)多态前提:
有继承关系;
有方法重写;
有父类引用指向子类对象。父 f = new 子();
(2)多态中成员访问特点:
A:成员变量
编译看左边,运行看左边。
B:成员方法
编译看左边,运行看右边。(因为子类方法重写掉父类中方法)。
子类中有和父类一样的方法,叫重写。
子类中没有父亲中出现过的方法,方法就被继承过来了。
class A {
public void show(){
show2();
}
public void show2(){
System.out.println("我");
}
}
class B extends A {
/*public void show(){
show2();
}*/
public void show2(){
System.out.println("爱");
}
}
class C extends B {
public void show(){
super.show();
}
public void show2(){
System.out.println("你");
}
}
public class Test2 {
/**
* @param args
*/
public static void main(String[] args) {
A a = new B();
a.show(); //爱
B b=new C();
b.show(); //你
}
}
C:构造方法
创建子类对象的时候,访问父类的构造方法,对父类的数据进行初始化。
D:静态方法
编译看左边,运行看左边。(静态和类相关,算不上重写,所以,访问的还是左边的。)
class Fu{
public int num=100;
public void show(){
System.out.println("show Fu");
}
public static void function(){
System.out.println("function Fu");
}
}
class Zi extends Fu{
public int num =1000;
public int num2=200;
public void show(){
System.out.println("show Zi");
}
public void method(){
System.out.println("method zi");
}
public static void function(){
System.out.println("function Zi");
}
}
public class Duotai {
/**
* 多态前提:
* (1):继承
* (2):重写
* (3):要有父类引用指向子类对象。
*/
public static void main(String[] args) {
Fu f = new Zi();
//System.out.println(f.num);
//System.out.println(f.num2);//num2 cannot be resolved or is not a field:找不到符号
//f.show();//show zi
//f.method();//The method method() is undefined for the type Fu
f.function();//function Fu
}
}
二、多态的好处:
A:提高了代码的维护性;
B:提高了代码的扩展性。
/*
多态的好处:
A:提高了代码的维护性(继承保证)
B:提高了代码的扩展性(由多态保证)
猫狗案例代码
*/
class Animal {
public void eat(){
System.out.println("eat");
}
public void sleep(){
System.out.println("sleep");
}
}
class Dog extends Animal {
public void eat(){
System.out.println("狗吃肉");
}
public void sleep(){
System.out.println("狗站着睡觉");
}
}
class Cat extends Animal {
public void eat() {
System.out.println("猫吃鱼");
}
public void sleep() {
System.out.println("猫趴着睡觉");
}
}
class Pig extends Animal {
public void eat() {
System.out.println("猪吃白菜");
}
public void sleep() {
System.out.println("猪侧着睡");
}
}
//针对动物操作的工具类
class AnimalTool {
private AnimalTool(){}
/*
//调用猫的功能
public static void useCat(Cat c) {
c.eat();
c.sleep();
}
//调用狗的功能
public static void useDog(Dog d) {
d.eat();
d.sleep();
}
//调用猪的功能
public static void usePig(Pig p) {
p.eat();
p.sleep();
}
*/
public static void useAnimal(Animal a) {
a.eat();
a.sleep();
}
}
class DuoTaiDemo2 {
public static void main(String[] args) {
//我喜欢猫,就养了一只
Cat c = new Cat();
c.eat();
c.sleep();
//我很喜欢猫,所以,又养了一只
Cat c2 = new Cat();
c2.eat();
c2.sleep();
//我特别喜欢猫,又养了一只
Cat c3 = new Cat();
c3.eat();
c3.sleep();
//...
System.out.println("--------------");
//问题来了,我养了很多只猫,每次创建对象是可以接受的
//但是呢?调用方法,你不觉得很相似吗?仅仅是对象名不一样。
//我们准备用方法改进
//调用方式改进版本
//useCat(c);
//useCat(c2);
//useCat(c3);
//AnimalTool.useCat(c);
//AnimalTool.useCat(c2);
//AnimalTool.useCat(c3);
AnimalTool.useAnimal(c);
AnimalTool.useAnimal(c2);
AnimalTool.useAnimal(c3);
System.out.println("--------------");
//我喜欢狗
Dog d = new Dog();
Dog d2 = new Dog();
Dog d3 = new Dog();
//AnimalTool.useDog(d);
//AnimalTool.useDog(d2);
//AnimalTool.useDog(d3);
AnimalTool.useAnimal(d);
AnimalTool.useAnimal(d2);
AnimalTool.useAnimal(d3);
System.out.println("--------------");
//我喜欢宠物猪
//定义一个猪类,它要继承自动物,提供两个方法,并且还得在工具类中添加该类方法调用
Pig p = new Pig();
Pig p2 = new Pig();
Pig p3 = new Pig();
//AnimalTool.usePig(p);
//AnimalTool.usePig(p2);
//AnimalTool.usePig(p3);
AnimalTool.useAnimal(p);
AnimalTool.useAnimal(p2);
AnimalTool.useAnimal(p3);
System.out.println("--------------");
//我喜欢宠物狼,老虎,豹子...
//定义对应的类,继承自动物,提供对应的方法重写,并在工具类添加方法调用
//前面几个必须写,我是没有意见的
//但是,工具类每次都改,麻烦不
//我就想,你能不能不改了
//太简单:把所有的动物都写上。问题是名字是什么呢?到底哪些需要被加入呢?
//改用另一种解决方案。
}
/*
//调用猫的功能
public static void useCat(Cat c) {
c.eat();
c.sleep();
}
//调用狗的功能
public static void useDog(Dog d) {
d.eat();
d.sleep();
}
*/
}
三、多态的弊端:
不能使用子类特有的功能。
如何解决?
A:创建子类对象,调用方法即可。
这种方法可以,但是很多时候不合理,很占内存。
B :把父类的引用强制转换为子类的引用(向下转型)。
对象间的转型问题:
向上转型:
Fu f = new zi();
向下转型:
Zi z = (Zi) f;
class Fu {
public void show(){
System.out.println("show Fu");
}
}
class Zi extends Fu{
public void show(){
System.out.println("show Zi");
}
public void method(){
System.out.println("method zi");
}
}
public class Duotai3demo {
/**
* @param args
*/
public static void main(String[] args) {
Fu f = new Zi();
f.show();
//如果能够把子的对象赋值给父亲,那么能不能把父的引用赋值给子呢
Zi z = (Zi)f;
z.show();//show Zi
z.method();//method Zi
}
}
总结:
多态,指的是某一个事物,在不同时刻表现出来的不同状态。多态的前提条件,三者缺一不可。多态中成员访问特点,必须掌握。使用多态有利于提高代码维护性和可扩展性,这一点在上面的代码中很好的体现出来了。有优点必然有弊端,即父类不能使用子类特有的方法,这一点使用对象间的转型即可解决。