1:多态概述
代码中的多态:父类引用指向子类对象。Animal ani = new Dog();
狗是动物,这就是多态。
父类名称 变量名 = new 子类名称();
接口名称 对象名 = new 实现类名称();
多态是在继承或者实现关系的前提下。
使用多态后父类的变量名调用的是子类重写后的方法,但是无法调用父类没有的方法(可以用向下转型后调用)。
a instanceof A;判断a对象是否属于A这个数据类型。
2: 多态转型和使用举例
- 向上转型:多态本身就是向上转型的。
Animal ani = new Dog();
这就是多态。
一旦向上转型为父类,那么就无法调用子类原本特有的方法。这个时候要用对象的向下转型还原。 - 向下转型
使用格式:子类名称 变量名 = (子类名称)父类的变量名;
public class Animal {
public void smail() {
System.out.println("笑");
}
public void eat() {
System.out.println("什么都吃");
}
public void sleep() {
System.out.println("睡觉");
}
}
public class Dog extends Animal{
public void eat() {
System.out.println("吃骨头");
}
public void sleep() {
System.out.println("睡狗头大觉");
}
public void bark() {
System.out.print("汪汪汪");
}
}
public class Cat extends Animal{
public void CatchMouse() {
System.out.print("抓老鼠");
}
}
public class Test {
public static void main(String[] args) {
Animal ani = new Animal();
ani.sleep();//调用Animal中的sleep方法。
Animal aniA = new Dog(); //向上转型
aniA.smail();//子类没有这个方法,向上找,调用的是父类的方法。
aniA.eat();//如果是共有的方法,new的是谁,调用的是谁
aniA.bark();//报错,如果是子类特有方法。此时要向下转型,变回子类对象
Dog dog1 = (Dog)aniA;//向下转型,把父类对象还原成本来的子类对象。向下转型前我们先判断下是属于那个子类。然后调用相应方法
dog1.bark();//调用子类的特有方法。
//我们在这里判断一下aniA是什么在执行向下转型。适合有多个子类
public static void method(Animal aniA) {
if(aniA instanceof Dog) {
Dog dog1 = (Dog)ani1;//向下转型,把父类对象还原成本来的子类对象。向下转型前我们先判断下是属于那个子类。然后调用相应方法
dog1.bark();//调用子类的特有方法。
}
if(aniA instanceof Cat) {
Cat cat1 = (Cat)ani1;//向下转型,把父类对象还原成本来的子类对象。向下转型前我们先判断下是属于那个子类。然后调用相应方法
cat1 .CatchMouse();//调用子类的特有方法。
}
}
}
}
- 访问成员变量的方式:
通过对象名访问成员变量,看等号左边是谁优先用谁,没有则向上找。 - 访问成员方法:
new的是谁调用谁的方法,没有就向上找。
public class Fu() {
int num = 10;
public void sleep() {
System.out.println("睡觉");
}
}
public class Zi extends Fu() {
int num = 20;
public void sleep() {
System.out.println("写代码");
}
}
public class Test() {
public static void main(String[] args) {
Fu obj = new Zi();//父类成员变量引用到子类
System.out.print(obj.num);//等号左边是谁,调用的是谁的成员变量
obj.sleep();//如果是方法,则看new的是谁,就调用谁的方法。子类复写了父类的方法。
}
}
//10 等号左边是Fu,优先用等号左边的成员变量。
//写代码 new的是谁就调用谁的方法,没有就向上找。
3:为什么用多态:
创建对象的时候,左边是父类,右边可以是任意的子类。
public class Employee() {
public void work() {
System.out.print("工作");
}
public void salay() {
System.out.print("拿工资");
}
}
public class Teacher extends Employee() {
public void word() {
System.out.print("讲课");
}
}
public class Assistent extends Employee() {
public void work() {
System.out.print("辅导");
}
}
public class Test() {
public static void main(String[] args) {
Employee obj1 = new Teacher();
obj1.work();
Employee obj2 = new Assitent();
obj2.work();
}
}
//讲课 辅导
4:下面我们实现一个例子。
定义laptop笔记本电脑类,类中开机方法,连接USB方法(USB接口作为参数,调用其实现类方法),关机方法。
定义USB接口,接口有开启连接,关闭连接两种抽象方法。
定义一个Mouse类实现了USB接口,那么Mouse类本身也是一个USB设备,重写了USB的抽象方法,又定义了一个鼠标点击方法。
定义一个Keyboard类实现了USB接口,重写了USB的抽象方法,又定义了键盘输入的方法。
要点:用到了多态
laptop类:
public class Laptop {
public void powerOn() {
System.out.println("打开电脑");
}
public void powerOff() {
System.out.print("关闭电脑");
}
public void useDevice(Usb usb) {//把usb接口作为参数传入
//使用设备需要用到usb类的打开设备和关闭设备
usb.open();
if(usb instanceof Mouse) {//判断传入的usb是否是属于Mouse
Mouse mouse = (Mouse)usb;
mouse.click();//向下转型调用Mouse中的特有的方法。
}else if(usb instanceof Keyboard) {
Keyboard keyb = (Keyboard)usb;
keyb.Type();//向下转型Keyboard,调用其方法。
}
usb.close();//调用usb的关闭方法。
}
}
USB接口:
public abstract interface Usb {
//usb实现了两个抽象方法
public abstract void open();
public abstract void close();
}
Mouse实现类
public class Mouse implements Usb {
@Override
public void open() {
System.out.println("开启鼠标");
}
public void click() {
System.out.println("鼠标点击");
}
@Override
public void close() {
System.out.println("关闭鼠标");
}
//鼠标是一个usb设备,实现usb的抽象方法。
}
Keyboar实现类:
public class Keyboard implements Usb{
@Override
public void open() {
System.out.println("连接键盘");
}
public void Type() {
System.out.println("键盘输入");
}
@Override
public void close() {
System.out.println("关闭键盘");
}
}
实现开机,使用usb设备,关机。
public class Test {
public static void main(String[] args) {
//新建一个laptop对象,调用laptop的方法
Laptop laptop = new Laptop();
laptop.powerOn();//打开电脑
Usb usbMouse = new Mouse();//多态,Mouse鼠标是一个usb设备
laptop.useDevice(usbMouse);//把这个usb设备作为laptop中方法的参数传入
Usb usbKeyboard = new Keyboard();//多态,直接用父类指向子类
laptop.useDevice(usbKeyboard);//传入参数
//向上转型后,仍不能调用子类特有的方法,需要调用方法进行向下转型,调用子类特有方法。
Mouse mouse = new Mouse();
laptop.useDevice(mouse);//Mouse继承自Usb,实现类自动向上转型为
laptop.useDevice(new Keyboard());//自动向上转型
laptop.powerOff();//关闭电脑
}
}
打开电脑
开启鼠标 鼠标点击 关闭鼠标
连接键盘 键盘输入 关闭键盘
关闭电脑