各位看官们,大家好,上一回中咱们说的是Java中继承的例子,这一回咱们说的例子是Java中的多态。闲话休提, 言归正转。让我们一起Talk Android吧!
看官们,我们今天介绍的内容是面向对象知识中的精华:多态。多态体现为子类对象向父类对象的转换,以及通过父类对象调用子类对象的方法。这么说肯定是很抽象的,还和以前一样,我们通过伪代码来演示多态。
class A
{
permission type valA;
permission func1()
{
//do something
}
};
class B extends A
{
permission type valB;
permission func1()
{
//do something
};
permission func2()
{
//do something
}
};
A objA = new A();
B objB = new B();
objA.func1(); // call the func1 of A
objB.func1(); // call the func1 of B
objA = objB; // change the type of class, but can't do this: objB = objA;
objA.func1(); // call the func1 of B
objA.func2(); // can't call the func2 of B
上面的代码中,类B继承于类A,它除了继承到类A的成员变量和成员函数外,它还定义了自己的成员变量valB和成员函数func2。不过它也定义了一个成员函数func1
,从继承的角度看,它已经从类A继承了成员函数func1
,它自己再定义一个func1,是不是就有两个成员函数func1了呢?不是这样的,它只有一个成员函数func1。按照Java中的语法规则来看,如果类A中的func1
是抽象函数,那么类B的这种做法叫作实现;如果类A中的func1
不是抽象方法,那么类B的这种做法叫重写或者覆写(覆盖)
。在我们的伪代码中,显然是类B重写了类A中的func1
方法。重写使的我们可以使用类A的对象objA调用类B中的方法func1
,这便是多态。
从伪代码中我们也可以看到,如果没有重写方法的话,类A的对象是不能调用类B中的方法func2。
关于重写,需要注意的是子类和父类的中函数原型必须完全一致,这样才能算作子类重写了父类的方法,如果函数原型不一致,那么就不是重写了,那是什么呢?这时有看官说:重载。没错,就是重载。这是一种跨类的函数重载
。这种函数重载跨越了类的继承体系结构,比起在同一个类中重载来说,这种跨类的重载不容易发现。看来刚才回答的看官有一双雪亮的眼睛呀,哈哈。
我们继续看上面的伪代码,类B的对象objB可以转换为类A的对象objA,这也是一种多态,反之则不可以。不过如果如果类A的对象是从类B的对象转换过来的,那么它还可以再转换回原来的类型。也就是说:如果先执行objA = objB
后,那么就可以执行objB = objA
。
类型的转换容易发生错误,因此我建议大家在转换前使用instanceof关键字,它可以判断某个对象的类型。它的用法如下:
object instanceof ClassName;
如果object的类型属于ClassName的类型,那么它返回true,否则返回false。我们结合上面的伪代码再写以下伪代码:
A objA = new A();
B objB = new B();
objA instanceof A; //it return true
objB instanceof B; //it return true
objA instanceof B; //it return false
objB instanceof A; //it return false
objA = objB; // change the type of class
objA instanceof A; //it return true
objA instanceof B; //it return true
从上面的伪代码中可以看到,通过instance关键字可以判断出某个对象的类型,进而为不同类型对象的转换创造出安全的前提条件。当然了,它只适用于Class类型,其它基本的类型(比如int),是不适用的。
看官们,多态是面对对象知识中比较重要而且难理解的知识,希望大家结合我们提供的伪代码来思考,这样会容易理解一些,而且可以把抽象的知识转换具体的知识,在以后写代码的时候也会使用到。
各位看官,关于Java中多态的例子咱们就介绍到这里,欲知后面还有什么例子,且听下回分解!