多态:
水是(液态,固态,气态)
多肽的前提:
1-要有继承关系
2-要有方法重写(来体现不同状态)
如果不写方法重写,就失去了多肽的意义
动物 dw = new 狗();
dw.show();//狗表现的状态
动物 dw = new 猫();
dw.show();//猫表现的状态
3-要有父类引用指向子类
父类 f = new 子类() ;
左边 右边
多态中的成员访问特点:
父类 f = new 子类() ;
左边 右边
1-成员变量 :
编译看左边,运行看左边(变量不存在覆盖)
2-构造方法:创建子类对象时候,访问父类的构造方法,对父类数据进行初始化。
3-成员方法:
编译看左边,编译看右边。(方法存在覆盖)
4-静态方法:
编译看左边,运行看左边(静态只能被静态重写,静态和类相关)
注意:由于只有成员方法存在方法重写,所以它运行看右边。
案例:
猫吃老鼠
猫打着呼噜睡觉
狗吃骨头
狗趴着睡觉
猪吃饲料
猪侧着睡觉
思考:假如有很多类呢......
引入 工具类AnimalTool,由于测试类里面的操作就是创建对象和调用操作,顾新建一个工具类存放功能方法
那么以上代码就可以改为
猫吃老鼠
猫打着呼噜睡觉
狗吃骨头
狗趴着睡觉
猪吃饲料
猪侧着睡觉
***************借助工具类调用*****************
猫吃老鼠
猫打着呼噜睡觉
狗吃骨头
狗趴着睡觉
猪吃饲料
猪侧着睡觉
***************借助工具类改进版调用*****************
猫吃老鼠
猫打着呼噜睡觉
狗吃骨头
狗趴着睡觉
猪吃饲料
猪侧着睡觉
同一个(事物)对象在不同时刻表现出的不同的状态。
例:
狗是狗,狗是动物水是(液态,固态,气态)
多肽的前提:
1-要有继承关系
2-要有方法重写(来体现不同状态)
如果不写方法重写,就失去了多肽的意义
动物 dw = new 狗();
dw.show();//狗表现的状态
动物 dw = new 猫();
dw.show();//猫表现的状态
3-要有父类引用指向子类
父类 f = new 子类() ;
左边 右边
多态中的成员访问特点:
父类 f = new 子类() ;
左边 右边
1-成员变量 :
编译看左边,运行看左边(变量不存在覆盖)
2-构造方法:创建子类对象时候,访问父类的构造方法,对父类数据进行初始化。
3-成员方法:
编译看左边,编译看右边。(方法存在覆盖)
4-静态方法:
编译看左边,运行看左边(静态只能被静态重写,静态和类相关)
注意:由于只有成员方法存在方法重写,所以它运行看右边。
案例:
package day09;
public class Fu {
public int num=100;
public void show(){
System.out.println("父类方法");
}
}
package day09;
public class Zi extends Fu {
public int num=333;
public int num2=444;
public void show(){
System.out.println("子类方法");
}
public void method(){
System.out.println("子类独有方法!");
}
}
package day09;
public class ZiFuMain {
/**
* @param args
*/
public static void main(String[] args) {
//创建指向子类的父类引用
Fu f = new Zi();
System.out.println(f.num);//输出父类的num,编译看左边,运行看左边
//System.out.println(f.num2);//报错,编译看左边,左边父类中没有num2变量
f.show();//编译看左边,左边父类show方法被子类重写,顾运行看右边
//f.method();//报错,编译看左边父类没有method()方法,所以报错。
}
}
输出:
100
子类方法
多态的好处:
1-提高了代码的维护性
2-提高了代码的扩展性
下面来演示一个显示多态扩展性的案例:
cat类:
package day09;
public class Cat extends Animal {
public void eat(){
System.out.println("猫吃老鼠");
}
public void sleep(){
System.out.println("猫打着呼噜睡觉");
}
}
dog类:
package day09;
public class Dog extends Animal{
public void eat(){
System.out.println("狗吃骨头");
}
public void sleep(){
System.out.println("狗趴着睡觉");
}
}
pig类:
package day09;
public class Pig extends Animal {
public void eat(){
System.out.println("猪吃饲料");
}
public void sleep(){
System.out.println("猪侧着睡觉");
}
}
测试类1:
package day09;
public class MianDemo {
/**
* @param args
*/
public static void main(String[] args) {
Cat c = new Cat();
c.eat();
c.sleep();
// 创建Dog对象
Dog d = new Dog();
d.eat();
d.sleep();
// 创建Pig对象
Pig p = new Pig();
p.eat();
p.sleep();
}
}
输出:
猫吃老鼠
猫打着呼噜睡觉
狗吃骨头
狗趴着睡觉
猪吃饲料
猪侧着睡觉
思考:假如有很多类呢......
引入 工具类AnimalTool,由于测试类里面的操作就是创建对象和调用操作,顾新建一个工具类存放功能方法
那么以上代码就可以改为
package day09;
public 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();
}
}
测试类2:
package day09;
public class MainDemo2 {
/**
* @param args
*/
public static void main(String[] args) {
System.out.println("***************方法直接调用版本*****************");
// 创建Cat对象
Cat c = new Cat();
c.eat();
c.sleep();
// 创建Dog对象
Dog d = new Dog();
d.eat();
d.sleep();
// 创建Pig对象
Pig p = new Pig();
p.eat();
p.sleep();
System.out.println("***************借助工具类调用*****************");
AnimalTool.useCat(c);
AnimalTool.useDog(d);
AnimalTool.usePig(p);
}
}
输出:
***************方法直接调用版本*****************
猫吃老鼠
猫打着呼噜睡觉
狗吃骨头
狗趴着睡觉
猪吃饲料
猪侧着睡觉
***************借助工具类调用*****************
猫吃老鼠
猫打着呼噜睡觉
狗吃骨头
狗趴着睡觉
猪吃饲料
猪侧着睡觉
重点:思考工具类,加入我还想创建老虎,狮子,长颈鹿,企鹅....等等等动物呢,程序显得很臃肿,万一不小心把以上代码改动,还会造成程序错误。
有什么好的解决方法么???
答:使用父类创建子类引用方式。
则工具类代码将更改为(最后//代码改进**************以下的部分)
package day09;
public 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();
}
}
三种调用方法最终测试类:
package day09;
public class AnimalMain {
/**
*
*/
public static void main(String[] args) {
System.out.println("***************方法直接调用版本*****************");
// 创建Cat对象
Cat c = new Cat();
c.eat();
c.sleep();
// 创建Dog对象
Dog d = new Dog();
d.eat();
d.sleep();
// 创建Pig对象
Pig p = new Pig();
p.eat();
p.sleep();
// 思考:假如有很多类呢......
// 引入工具类AnimalTool,由于测试类里面的操作就是创建对象和调用操作,顾新建一个工具类存放功能方法
// 那么以上代码就可以改为
System.out.println("***************借助工具类调用*****************");
AnimalTool.useCat(c);
AnimalTool.useDog(d);
AnimalTool.usePig(p);
//根据工具类里面的父类指向子类的引用,代码又可以进一步改进为一下调用方式(推荐使用)
System.out.println("***************借助工具类改进版调用*****************");
AnimalTool.useAnimal(c);
AnimalTool.useAnimal(d);
AnimalTool.useAnimal(p);
}
}
***************方法直接调用版本*****************
猫吃老鼠
猫打着呼噜睡觉
狗吃骨头
狗趴着睡觉
猪吃饲料
猪侧着睡觉
***************借助工具类调用*****************
猫吃老鼠
猫打着呼噜睡觉
狗吃骨头
狗趴着睡觉
猪吃饲料
猪侧着睡觉
***************借助工具类改进版调用*****************
猫吃老鼠
猫打着呼噜睡觉
狗吃骨头
狗趴着睡觉
猪吃饲料
猪侧着睡觉