java多态的两种语言_Java语言中的多态性

概述

多态是面向对象的三大特征之一,另外两个是封装、继承。

之前看过一个对多态很形象的解释:如果编译时类型和运行时类型不一样的话,就会出现多态。

编译时类型与运行时类型

这里有编译时类型和运行时类型,这是因为Java有点特别,因为java代码都要编译成*.class文件(此阶段叫编译),然后*.class文件在JVM里面运行(此阶段叫运行)。所以,这两种类型的区别之处就在于:

1、编译时类型就是在声明一个变量时,指定该变量的类型。

2、而运行时类型,就是真正赋值给这个变量的值的类型。

为了方便理解,下面举一个简单的例子:

double a = 10;

上面这行代码中,声明了一个变量,变量的编译时类型是double类型,而赋值给a的值是int类型,所以a的运行时类型是int。这个例子只是为了方便理解,解释不一定正确。

对象中的多态

直接看例子吧:

class BaseClass{

public int age = 100;

public void showInfo(){

System.out.println("Base class showInfo");

}

public void say(){

System.out.println("Base class say");

}

}

class SubClass extends BaseClass{

public int age = 200;

public String name = "demo";

public void say(){

System.out.println("Sub class say");

}

public void speak(){

System.out.println("sub class speak");

}

}

public class Test{

public static void main(String[] args){

BaseClass bc = new SubClass();

// 注意,BaseClass是编译时类型,而SubClass是运行时类型

bc.showInfo();

// Base class showInfo

bc.say();

// Sub class say

// 编译出错

// bc.speak();

System.out.println(bc.age);

// 100

// 编译出错

// System.out.println(bc.name);

}

}

多态的原则(结论),有几个注意点:

1、编译时类型必须是运行时类型的父类或者间接父类。编译时类型不能是运行时类型的子类。可以形象记忆:父类比子类范围大,将父类赋值给子类,会有精度损失,所以会出错。

2、子类可以继承、覆盖父类的成员属性,或者增加自己的成员属性;同样子类也可以继承、重写父类的成员方法,或者增加自己的成员方法。

3、创建的对象(编译时类型为父类类型,运行时类型为子类类型),通过该对象,只能访问或者调用编译类型的成员属性和成员方法(父类中定义的成员属性和成员方法),而不能访问子类中新增的成员属性和成员方法。这是在编译阶段需要注意的,如果通过该对象访问子类中的成员属性和成员方法,就会报错。

4、前面已经说了,通过对象引用,只能访问或者调用两个类中共有的那些成员属性和方法。但是前面也,在子类中,子类是可以覆盖或者重写从父类中继承过来的成员属性和成员方法。

I、对于成员属性来说:无论在子类中是否覆盖父类中的成员属性,在真正运行时,访问该成员属性,得到的值都是父类中那个成员属性值(即使子类重写之后赋了其他值)。

II、对于成员方法来说:如果子类中没有重写父类中的方法,那么调用的就是父类中的成员方法;如果子类中重写了父类中的方法,那么运行时调用的就是子类中重写之后的成员方法。

5、如果非要使用子类中新增的成员属性或者覆盖的成员属性,或者新增的成员方法,可以使用(type)variable来强制将编译类型为父类,运行类型为子类的对象转换为子类类型,之后就可以了。

class BaseClass{

public int age = 100;

public void showInfo(){

System.out.println("Base class showInfo");

}

public void say(){

System.out.println("Base class say");

}

}

class SubClass extends BaseClass{

public int age = 200;

public String name = "demo";

public void say(){

System.out.println("Sub class say");

}

public void speak(){

System.out.println("sub class speak");

}

}

public class Test{

public static void main(String[] args){

BaseClass bc = new SubClass();

bc.showInfo();

// Base class showInfo

bc.say();

// Sub class say

// 编译错误

// bc.speak();

((SubClass)bc).speak();

// sub class speak

System.out.println(bc.age);

// 100

// 编译错误

// System.out.println(bc.name);

System.out.println(((SubClass)bc).name);

// demo

}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值