当前位置: > 财经>正文

java中类继承,到底继承了什么? 信托产品可以继承吗为什么不能贷款

2023-09-02 01:37:56 互联网 未知 财经

java中类继承,到底继承了什么?

 

继承的最大好处就是为了实现代码的复用。那么,子类到底从父类得到的什么呢?

 

实例成员

 

父类的private成员不会被子类继承,子类不能访问。但是子类对象的确包含父类的私有成员。父类的 包访问成员 继承为子类的包访问成员。就好像他们直接定义在子类中一样。父类的 protected 成员继承为子类的protected 成员。就好像他们直接定义在子类中一样。父类的 public 成员继承为子类的public 成员,就好像他们直接定义在子类中一样。

 

实例方法

 

继承到的实例方法在子类中可以直接被使用,还需重点理解是方法的重写和重载。

 

重写override

一个继承链中,父类的方法对于子类来说具有相同的语义,但是不同的细节操作,因此子类需要override父类的这个方法以满足自己的需求。

注意的点:

1、方法名,参数表一定和父类中的相同,返回类型相同,或者是子类。

1、访问权限一定不低于父类的实例方法

2、抛出的异常一定是父类方法抛出的异常相同,或者子类。

 

 

如果拿C++和java对比,那么java中的实例方法默认都是virtual的(java中没有virtual这个key word),因此在java中,子类可以直接重写父类方法的任何非final实例方法,但是在C++中,除非父类使用virtual标记一个方法为虚方法,子类才可以override这个方法。

对于重写的方法,javac是不能确定的具体要调用那个类的方法,而是产生特殊的字节码让jvm去动态决定什么方法。这个就是所谓的前期绑定和后期绑定的差异。

public class Test{ public static void main(String [] args){ Object o = new SubClass(); o.toString(); }}class SubClass extends Object{ public String toString() //重写Object 的toString方法 { return "SubClass"; }}

 

Compiled from "Test.java"public class Test { public Test(); Code: 0: aload_0 1: invokespecial #1 // Method java/lang/Object."":()V 4: return public static void main(java.lang.String[]); Code: 0: new #2 // class SubClass 3: dup 4: invokespecial #3 // Method SubClass."":()V 7: astore_1 8: aload_1 9: invokevirtual #4 // Method java/lang/Object.toString:()Ljava/lang/String; 12: pop 13: return}

 

其中3处红色标记 的代码,重要的区别就是invokespecial 和 invokevirtual :invokespecial 代表前期绑定,在编译期就能决定调用什么方法,由javac确定调用什么方法。invokevirtual 则是方法的后期绑定,由JVM决定调用什么方法。

第一处是Test类的构造函数调用父类Object的构造函数,编译期确定,他是前期绑定。

第二处是因为new 了一个SubClass对象,调用SubClass的构造函数,编译期确定,他也是前期绑定的。

第三处是因为我们的 Object o 引用了重写了toString方法的SubClass对象,javac不能知道具体调用Object中的toString,还是SubClass中的toString,于是产生特殊代码让JVM去决定。

修饰为 static  、 final 、private 的方法一定是前期绑定,因为他们根本都不存在override。

 

JVM需要在运行时动态决定调用那个版本的方法,这个过程对JVM来说就是 virtual method lookup(虚方法查找)。JVM将会从实际对象所属的类 和 他的最近的父类中查找。如果自己定义了,则调用自己的版本,如果没有则调用父类的版本。

 

重载overload

重载的定义:函数重载是指在同一作用域内,可以有一组具有相同函数名,不同参数列表的函数,这组函数被称为重载函数。

注意:重载与否,不考虑函数的返回类型。C++也是如此。也就是说,2个函数的返回类型同不同都不影响他们能不能形成重载,只要他们函数名相同,参数表不同就满足重载。

Java是默认是支持跨类重载的。但是C++就默认不支持在子类中重载父类的实例方法。那也就是说:java中的实例方法会自动导入到子类的作用域中,而C++则不是。

public class Test{ public static void main(String[] args) { Derive d = new Derive(); d.print("hello", 2); d.print("world");

/* outputhellohelloworldworldworldworldworld

*/

}}

class Base{ public void print(String msg) { for(int i=0;i

版权声明: 本站仅提供信息存储空间服务,旨在传递更多信息,不拥有所有权,不承担相关法律责任,不代表本网赞同其观点和对其真实性负责。如因作品内容、版权和其它问题需要同本网联系的,请发送邮件至 举报,一经查实,本站将立刻删除。