一. 理解多态
- 多态的前提:可以是继承关系(类和类)也可以是实现关系(接口和实现类)
在开发中一般都指第二种。 - 多态:对象具有多种形态,对象可以存在不同的表现形式。
Animal a = new Dog();
-
对象(a)的两种类型:
编译类型:声明对象变量的类型,Animal,表示把对象看成什么类型。
运行类型:对象的真实类型,Dog,运行类型->对象的真实类型 -
多态的特点:
把子类对象赋给父类变量,在运行时期会变现出具体的子类特征。
新减PolymorphismDemo.java
//多态的Demo
class Animal
{
void eat(){
System.out.println("吃普通食物");
}
}
class Dog extends Animal
{
void eat(){
System.out.println("吃肉骨头");
}
}
class Cat extends Animal
{
void eat(){
System.out.println("吃鱼肉肉");
}
}
class PolymorphismDemo
{
public static void main(String[] args)
{
Animal a;
a = new Dog();
a.eat();
a = new Cat();
a.eat();
}
}
二.多态的优点
- 多态作用:当把不同的子类对象都当作父类类型来看待,可以屏蔽不同子类对象之间的实现差异,
从而写出通用的代码达到代码通用,以适应需求的不断变化。
没有使用多态时,得提供不通对象提供不同方法。
- 使用多态时,指提供一个方法即可。
修改PolymorphismDemo.java
//多态的Demo
class Animal
{
void eat(){
System.out.println("吃普通食物");
}
}
...
//饲养员
class Person
{
void feed(Animal a){
System.out.println("喂养中......");
a.eat();
}
}
class PolymorphismDemo
{
public static void main(String[] args)
{
Animal a;
Person p = new Person();
a = new Dog();
p.feed(a);
a = new Cat();
p.feed(a);
}
}
三.多态时方法调用问题
-
前提:必须先存在多态的情况。
-
存在父类:SuperClass,子类SubClass,方法doWork
测试代码SuperClass s = new SubClass(); s.doWork();
- 情况1:
doWork存在SuperClass中,不存在SubClass中,
//父类 class SuperClass { public void doWork(){ System.out.println("Super.doWork"); } } //子类 class SubClass extends SuperClass { }
执行结果:编译通过,执行SuperClass的doWork()方法。
应该先从SubClass类中去找doWork方法,找不到,再到父类SuperClass中找。- 情况2:
doWork存在SubClass中,不存在SuperClass中。
//父类 class SuperClass { } //子类 class SubClass extends SuperClass { public void doWork(){ System.out.println("Sub.doWork"); } }
执行结果:编译报错。会去编译类型(SuperClass)中去找,
找不到编译报错,找到编译通过。- 情况3:
doWork存在SuperClass方法中,也存在SubClass中。
//父类 class SuperClass { public void doWork(){ System.out.println("Super.doWork"); } } //子类 class SubClass extends SuperClass { public void doWork(){ System.out.println("Sub.doWork"); } }
执行结果:编译通过,执行SuperClass的doWork方法。
应该先从SubClass类中去找doWord方法,找不到再去父类SuperClass方法。- 情况4:
doWork方法存在于SuperClass和SubClass中,但是doWork是静态方法。
此时称之为隐藏,不叫覆盖。
//父类 class SuperClass { static public void doWork(){ System.out.println("Super.doWork"); } } //子类 class SubClass extends SuperClass { static public void doWork(){ System.out.println("Sub.doWork"); } }
执行结果:编译通过,执行SuperClass的doword方法。
静态方法的调用只需要类即可。
如果使用对象来调用静态方法,其实时候的是对象的编译类型来调用静态方法。
和对象没有关系。 - 情况1:
四.引用类型转换
- 引用类型的父类和子类之间的转换转换关系。
- 自动类型转换:把子类对象赋值给父类变量(多态);
Animal a = new Dog();
Object obj = new Dog();
- 强制类型转换:把父类类型对象赋值给子类类型变量(该父类类型变量的真实类型应该是子类类型)。
Animal a = new Dog();
Dog d = (Dog)a;
- instanceof 运算符:判断该对象是否某一个类的实例
- 若对象是类的实例返回true
- 若对象是类的父类的实例返回true
- 语法格式:boolean b = 对象A instanceof 类B;//判断A对象是否是B类的实例,如果是,返回true
getClass()获取真实类型。
修改PolymorphismDemo.java
//多态的Demo
class Animal
{
void eat(){
System.out.println("吃普通食物");
}
}
//狗狗
class Dog extends Animal
{
void eat(){
System.out.println("吃肉骨头");
}
public void watch(){
System.out.println("看门");
}
}
//猫猫
class Cat extends Animal
{
void eat(){
System.out.println("吃鱼肉肉");
}
public void catchMouse(){
System.out.println("逮老鼠");
}
}
//饲养员
class Person
{
void feed(Animal a){
System.out.println("喂养中......");
a.eat();
if (a instanceof Dog)
{
Dog d = (Dog)a;
d.watch();
}else{
Cat c =(Cat)a;
c.catchMouse();
}
}
}
class PolymorphismDemo
{
public static void main(String[] args)
{
Animal a;
Person p = new Person();
Dog d = new Dog();
p.feed(d);
Cat c = new Cat();
p.feed(c);
Object o = "ABC";
System.out.println(o instanceof Object);//true
System.out.println(o instanceof String);//true
System.out.println(o.getClass() == Object.class);//false
System.out.println(o.getClass() == String.class);//true
}
}