某一事物,在不同时刻表现出来的不同状态
例如:
水:
固态、液态、气态
固态的水是水、液态的水也是水、气态的水也是水
水果:
波罗蜜、香蕉、榴莲
波罗蜜是水果、香蕉是水果、榴莲是水果
水果是波罗蜜,这么说是不可以的。
动物:
狗、虎、猫、大象
狗是动物,这么说是没问题的
动物是狗,这么说是不可以的。
1、要有继承关系 2、要有方法的重写。 其实没有重写也是可以的,但是不重写就没有意义 动物都有吃这个方法,但是每个具体的动物吃的实现不一样,变现出不同动物的特有属性 3、要有父类的引用指向子类对象
格式
父类名 f = new 子类名(…);
1、成员变量
编译看左,运行看左
2、构造方法(初始化作用)
创建子类对象的时候,先访问父类中的构造方法,对父类的数据先进行初始化
3、成员方法
编译看左,运行看右。
因为成员方法存在重写,所以访问看右边
4、静态成员方法
编译看左,运行也看左。
(由于被static修饰的成员都是与类相关的,这里不是重写,所以运行的时候,访问的还是左边的)
代码示例:
package com.shujia.wyh.day11; class Fu3{ int num = 100; public void show(){ System.out.println("这是父类中show()方法"); } public static void fun(){ System.out.println("这是父类中的静态fun方法"); } } class Zi3 extends Fu3{ int num = 1000; @Override public void show(){ System.out.println("这是子类中的show()方法"); } public void show2(){ System.out.println("这是子类特有的方法1"); } public static void fun(){ System.out.println("这是子类中的静态fun方法"); } } public class PolymorphicDemo1 { public static void main(String[] args) { //多态创建了一个对象 Fu3 f = new Zi3();//父类指向子类对象 System.out.println(f.num);//100 f.show(); // 这是子类中的show()方法 f.fun();//这是父类中的静态fun方法 } }
1、多态可以使代码的扩展性很好(这是由继承所保证的)
2、多态可以使代码的维护性很好(这是由多态保证的)
代码示例:
package com.shujia.rx.day12; class Animal{ String name; int age; public Animal() { } public Animal(String name, int age) { this.name = name; this.age = age; } public void sleep(){ System.out.println("睡觉"); } public void eat(){ System.out.println("吃"); } } class Dog extends Animal{ public Dog() { } public Dog(String name, int age) { super(name, age); } @Override public void sleep() { System.out.println("狗侧着睡"); } @Override public void eat() { System.out.println("狗吃肉"); } } class Cat extends Animal{ public Cat() { } public Cat(String name, int age) { super(name, age); } @Override public void sleep() { System.out.println("猫趴着睡"); } @Override public void eat() { System.out.println("????吃鱼"); } } //用工具类改进 class AnimalTool{ public static void useAnimal(Animal animal){ //Animal animal=new Cat("小白",9); //利用了多态访问成员方法的特点,编译看左,运行看右,实际调用的是子类对象中的方法。 animal.sleep(); animal.eat(); } } public class CatDogDemo { public static void main(String[] args) { //养一只狗 Dog d1 = new Dog("小黄",7); d1.sleep(); d1.eat(); useDog(d1); //养一只猫 Cat c1 = new Cat("小白",9); c1.sleep(); c1.eat(); AnimalTool.useAnimal(c1); } //用方法改进 public static void useDog(Dog dog){ dog.sleep(); dog.eat(); } }
多态无法访问父类中方法名一样的方法
如果我想使用子类中的特有方法,还必须使用多态,怎么办呢?
1)就不使用多态,创建子类对象然后调用方法,但是再次创建对象,还会在堆内存中开辟空间,很有可能会造成资源浪费。
2)java考虑到这样的问题,提供了一个技术给我们使用:向下转型
将父类的引用强制转换成子类的引用
格式:
子类类名 变量名 = (子类类名)父类的引用;
注意:
要求转型的类与父类引用存在继承关系,并且一开始创建多态的时候,使用的是该类。
代码示例:
向下转型猫狗案例
class Animal2{ public void eat(){ System.out.println("吃"); } } class Dog2 extends Animal2{ @Override public void eat() { System.out.println("狗吃肉"); } public void lookDoor(){ System.out.println("看门"); } } class Cat2 extends Animal2{ @Override public void eat() { System.out.println("猫吃鱼"); } public void catchMouse(){ System.out.println("猫捉老鼠"); } } public class PolymorphicDemo4 { public static void main(String[] args) { //以多态的形式创建一个对象 Animal2 a = new Dog2(); a.eat(); // a.lookDoor(); //向下转型访问子类中特有的方法 Dog2 d = (Dog2) a; d.eat(); d.lookDoor(); //ClassCastException类转换异常 Cat2 c = (Cat2) a; // 此刻内存中还是一个Dog2的对象,内存图解如下: c.catchMouse(); } }
代码示例:
不同地方饮食文化不同的案例
package com.shujia.wyh.day11; /* 不同地方饮食文化不同的案例 Person eat() SouthPerson eat() NorthPerson eat() */ class Person{ public void eat(){ System.out.println("吃"); } } class SouthPerson extends Person{ @Override public void eat() { System.out.println("南方人吃米饭"); } public void playMaJiang(){ System.out.println("南方人打麻将"); } } class NorthPerson extends Person{ @Override public void eat() { System.out.println("北方人吃面食"); } public void bath(){ System.out.println("北方人搓澡"); } } public class PolymorphicDemo5 { public static void main(String[] args) { //多态创建南方人对象 Person p = new SouthPerson(); p.eat(); // p.playMaJiang(); //向下转型 SouthPerson sp = (SouthPerson) p; sp.eat(); sp.playMaJiang(); //多态创建北方人对象 Person p2 = new NorthPerson(); p2.eat(); // p2.bath(); //向下转型 NorthPerson np = (NorthPerson) p2; np.eat(); np.bath(); } }