Java运行时多态性:继承和通达信 通达信 接口 数据结构,接口 数据结构,通达信 接口 数据结构,接口的实现
输出结果为:
这个很好理解,因为private说明该方法对子类是不可见的,子类再写一个同名的方法并不是对父类方法进行复写(Overrid,而是重新生成一个新的方法,也就不存在多态的问题了。同理也可以解释final,因为方法同样是不可覆盖的。
代码如下所示.
class Base {
public static void staticMethod() {
System.out.println('Base staticMehtod');
}
public void dynamicMehtod() {
System.out.println('Base dynamicMehtod');
}
}
class Sub extends Base {
public static void staticMethod() {
System.out.println('Sub staticMehtod');
}
public void dynamicMehtod() {
System.out.println('Sub dynamicMehtod');
}
}
public class TJ4 {
public static void main(String args[]) {
Base c = new Sub();
c.staticMethod();
c.dynamicMehtod();
}
}
通过通达信 通达信 接口 数据结构,接口 数据结构,通达信 接口 数据结构,接口类型变量引用实现通达信 通达信 接口 数据结构,接口 数据结构,通达信 接口 数据结构,接口的类的对象来实现
方法是static修饰的
举例说明:
//定义通达信 通达信 接口 数据结构,接口 数据结构,通达信 接口 数据结构,接口InterA
interface InterA
{
void fun();
}
//实现通达信 通达信 接口 数据结构,接口 数据结构,通达信 接口 数据结构,接口InterA的类B
class B implements InterA
{
public void fun()
{
System.out.println(“This is B”);
}
}
//实现通达信 通达信 接口 数据结构,接口 数据结构,通达信 接口 数据结构,接口InterA的类C
class C implements InterA
{
public void fun()
{
System.out.println(“This is C”);
}
}
class Test
{
public static void main(String[] args)
{
InterA a;
a= new B();
a.fun();
a = new C();
a.fun();
}
}
Java是面向对象的语言,而运行时多态性是面向对象程序设计代码重用的一个最强大机制,动态性的概念也可以被说成“一个通达信 通达信 接口 数据结构,接口 数据结构,通达信 接口 数据结构,接口,多个方法”。Java实现运行时多态性的基础是动态方法调度,它是一种在运行时而不是在编译期调用重载方法的机制,下面就继承和通达信 通达信 接口 数据结构,接口 数据结构,通达信 接口 数据结构,接口实现两方面谈谈java运行时多态性的实现。
不要被上例中和所迷惑,虽然写成fun(),但是由于中的a被b赋值,指向了子类subB的一个实例,因而所调用的fun()实际上是子类subB的成员方法fun(),它覆盖了超类superA的成员方法fun();同样调用的是子类subC的成员方法fun()。
基类方法是private或final修饰的
抽象类的子类必须覆盖实现超类中的所有的抽象方法,否则子类必须被abstract修饰符修饰,当然也就不能被实例化了。
上述代码中subB和subC是超类superA的子类,我们在类Test中声明了3个引用变量a,b,c,通过将子类对象引用赋值给超类对象引用变量来实现动态方法调用。也许有人会问:“为什么和不输出:ThisissuperA”。java的这种机制遵循一个原则:当超类对象引用变量引用子类对象时,被引用对象的类型而不是引用变量的类型决定了调用谁的成员方法,但是这个被调用的方法必须是在超类中定义过的,也就是说被子类覆盖的方法。
通过继承中超类对象引用变量引用子类对象来实现
通达信 通达信 接口 数据结构,接口 数据结构,通达信 接口 数据结构,接口的灵活性就在于“规定一个类必须做什么,而不管你如何做”。我们可以定义一个通达信 通达信 接口 数据结构,接口 数据结构,通达信 接口 数据结构,接口类型的引用变量来引用实现通达信 通达信 接口 数据结构,接口 数据结构,通达信 接口 数据结构,接口的类的实例,当这个引用调用方法时,它会根据实际引用的类的实例来判断具体调用哪个方法,这和上述的超类对象引用访问子类对象的机制相似。
运行结果为:
需要注意的一点是:Java在利用通达信 通达信 接口 数据结构,接口 数据结构,通达信 接口 数据结构,接口变量调用其实现类的对象的方法时,该方法必须已经在通达信 通达信 接口 数据结构,接口 数据结构,通达信 接口 数据结构,接口中被声明,而且在通达信 通达信 接口 数据结构,接口 数据结构,通达信 接口 数据结构,接口的实现类中该实现方法的类型和参数必须与通达信 通达信 接口 数据结构,接口 数据结构,通达信 接口 数据结构,接口中所定义的精确匹配。
上例中类B和类C是实现通达信 通达信 接口 数据结构,接口 数据结构,通达信 接口 数据结构,接口InterA的两个类,分别实现了通达信 通达信 接口 数据结构,接口 数据结构,通达信 接口 数据结构,接口的方法fun(),通过将类B和类C的实例赋给通达信 通达信 接口 数据结构,接口 数据结构,通达信 接口 数据结构,接口引用a,实现了方法在运行时的动态绑定,充分利用了“一个通达信 通达信 接口 数据结构,接口 数据结构,通达信 接口 数据结构,接口,多个方法”,展示了Java的动态多态性。
输出结果并不像设想的那样,输出“SubstaticMehtod”。因为静态方法是与类而不是与某个对象相关联,staticMethod();等同于Car.staticMethod();所以尽量不要使用实例变量去调用静态方法,避免混淆。
动态绑定机制使得基类的引用能够指向正确的子类对象,从而使得面向基类编程成为可能。然而动态绑定在以下两种情况会失效。
举例说明:
//定义超类superA
class superA {
int i = 100;
void fun() {
System.out.println(“This is superA”);
}
}
//定义superA的子类subB
class subB extends superA {
int m = 1;
void fun() {
System.out.println(“This is subB”);
}
}
//定义superA的子类subC
class subC extends superA {
int n = 1;
void fun() {
System.out.println(“This is subC”);
}
}
class Test {
public static void main(String[] args) {
superA a;
subB b = new subB();
subC c = new subC();
a = b;
a.fun();
(1)
a = c;
a.fun();
(2)
}
}
Java静态方法不具有多态性详解
如果子类继承的超类是一个抽象类,虽然抽象类不能通过new操作符实例化,但是可以创建抽象类的对象引用指向子类对象,以实现运行时多态性。具体的实现方法同上例。
需要注意的一点是:Java在利用通达信 通达信 接口 数据结构,接口 数据结构,通达信 接口 数据结构,接口变量调用其实现类的对象的方法时,该方法必须已经在通达信 通达信 接口 数据结构,接口 数据结构,通达信 接口 数据结构,接口中被声明,而且在通达信 通达信 接口 数据结构,接口 数据结构,通达信 接口 数据结构,接口的实现类中该实现方法的类型和参数必须与通达信 通达信 接口 数据结构,接口 数据结构,通达信 接口 数据结构,接口中所定义的精确匹配。
上例中类B和类C是实现通达信 通达信 接口 数据结构,接口 数据结构,通达信 接口 数据结构,接口InterA的两个类,分别实现了通达信 通达信 接口 数据结构,接口 数据结构,通达信 接口 数据结构,接口的方法fun(),通过将类B和类C的实例赋给通达信 通达信 接口 数据结构,接口 数据结构,通达信 接口 数据结构,接口引用a而实现了方法在运行时的动态绑定,充分利用了“一个通达信 通达信 接口 数据结构,接口 数据结构,通达信 接口 数据结构,接口,多个方法”展示了Java的动态多态性。
结束语:以上就是java运行时多态性的实现方法,大家在编程过程中可以灵活运用,但是在性能要求较高的代码中不提倡运用运行时多态,毕竟Java的运行时动态方法调用较之普通的方法调用的系统开销是比较大的。
扩展
输出结果为:
文章为作者独立观点,不代表观点