多态:一种事物的多种形态(状态)
一.多态的规则(前提)
1.类和类之间必须有关联(继承关系)
2.必须要有方法的重写(否则多态会没有意义)
3.(核心)父类的引用 指向 子类的空间(父类的指针 指向 子类对象)
代码例子:
public class Kll {
public static void main(String[] args) {
Animal a = new Animal();//父类的引用 指向 父类对象的空间
a.eat();
//父类的引用 指向 子类的空间
//使用多态的形式 创建对象
//调用方法 最后执行的是子类重写的方法
Animal a1 = new Cat();
a1.eat();
//意思同上
Animal a2 = new Dog();
a2.eat();
}
}
class Animal{
public void eat() {
System.out.println("吃");
}
}
class Cat extends Animal{
@Override//方法重写
public void eat() {
System.out.println("吃鱼");
}
}
class Dog extends Animal{
@Override//方法重写
public void eat() {
System.out.println("吃骨头");
}
}
二.引用数据类型是父类,那么该引用只能看见属于自己类型的那部分区域
当使用多态形式创建对象时
1.访问成员变量
编译时:需要看父类当中有没有该变量,没有就会报错
运行时:最终访问到的成员变量是父类中的成员变量
访问成员变量时,编译和运行都看父类的
2.访问成员方法
编译时:需要看父类中有没有该方法,没有就报错
运行时:最终运行时,入栈执行的是子类中重写的方法
访问成员方法时:编译时看父类,运行时看子类
代码例子:
public class Kll {
public static void main(String[] args) {
//不使用多态创建Father
Father f = new Father();
f.print();
System.out.println(f.num);
//使用多态的形式创建
Father s = new Son();
s.print();
System.out.println(s.num);
}
}
class Father{
int num = 10;
public void print() {
System.out.println("Father类的打印方法");
}
}
class Son extends Father{
int num1 = 20;
@Override//方法重写
public void print() {
System.out.println("Son类的打印方法");
}
}
在内存中运行的大致图是:
多态的好处:
1.提高工作效率,增强复用性(指的继承)
2.(核心)增强方法的扩展性
多态的弊端:
使用多态的形式创建对象,无法直接调用子类的特有方法
代码例子:
public class Kll {
public static void main(String[] args) {
//多态创建对象
//向上转型和向下转型
//将子类的对象做了一个向上转型
Person pC = new Cheat();
//调用共有的方法
pC.speak();
//调用子类特有方法
//需要将类型转回来(即向下转型)
//将转上去的类型转回来,才能调用子类的特有方法
//强转
//注意:必须是先向上转型,才能向下转型
Cheat c = (Cheat)pC;
c.hit();
}
}
class Person{
public void speak() {
System.out.println("聊天");
}
}
class Cheat extends Person{//骗子类
@Override//方法重写
public void speak() {
System.out.println("洗脑");
}
//特有方法
public void hit() {
System.out.println("打人");
}
}
关于多态中类型转换方法的代码例子:
public class Kll {
public static void main(String[] args) {
Arms arms = new Knife();
pickUpEquipment(arms);
}
//通用捡装备的方法
//使用父类当做方法的参数
//该方法可以接收武器类的所有子类
public static void pickUpEquipment(Arms a) {
a.hit();
//调用子类特有方法
//做一个类型判断
// instanceof 判断前面对象属不属于 后面这个类的对象
//类型一致 返回true 反之false
if (a instanceof Knife) {
//类型一致 才能进行向下转型
Knife k = (Knife)a;
k.practice();
}else if (a instanceof Sword) {
Sword s = (Sword)a;
s.exercise();
}
}
}
class Arms{//装备类
//打的方法
public void hit() {
System.out.println("打");
}
}
class Knife extends Arms{//刀类
@Override//方法重写
public void hit() {
System.out.println("砍砍砍");
}
//特有方法
public void practice() {
System.out.println("练刀");
}
}
class Sword extends Arms{//剑类
@Override//方法重写
public void hit() {
System.out.println("刺刺刺");
}
//特有的方法
public void exercise() {
System.out.println("练剑");
}
}