标签:垃圾 编译器 自身 pac ring 隐式 析构函数 extends 转型
复用代码是Java众多引人注目的功能之一。但要想成为极具革命性的语言,仅仅能够复制代码并对之加以改变是不够的,它还必须做更多的事情。
使用类而不破坏程序代码:
组合只需要将对象引用置于新类中就可以了。
但编译器并不是简单的为每一个引用都创建默认对象。如果想初始化这些引用,可以在代码中下列位置进行:
除非已明确指出要从其他类中继承,否则就是在隐式的从Java的标准根中类Object进行继承。
这种声明是通过在类主体的左边花括号之前,书写后面紧随基类名称的关键字extends而实现的。当这么做时,会自动得到基类中所有域和方法。
Javay用super关键字表示超类的意思。C#中用base。
当创建了一个导出类对象时,该对象包含了一个基类的子对象。这个子对象与你用基类直接创建的对象是一样的。二者区别在于,后者来自于外部,而基类的子对象被包装在导出类对象内部。
在构造器中调用基类构造器来执行初始化,而基类构造器具有执行基类初始化所需要的所有知识和能力。Java会自动在导出类的构造器中插入对基类构造器的调用。
即使你不为导出类创建构造器,编译器也会为你合成一个默认的构造器,该构造器将调用基类的构造器。
如果没有默认的基类构造器,或者想调用一个带参数的基类构造器,就必须使用关键字super显式的编写调用基类构造器的语句,并且配以适当的参数列表。
这是继承于组合之间的中庸之道,因为我们将一个成员对象置于所要构造的类中,但与此同时我们在新类中暴露了该成员对象的所有方法。
public class SpaceShipDelegation {
SpaceShipControls spaceShipControls=null;
public SpaceShipDelegation(SpaceShipControls controls){
this.spaceShipControls=controls;
}
public void up(int i){
spaceShipControls.up(i);
}
public void down(int i){
spaceShipControls.down(i);
}
}
class SpaceShipControls{
void up(int velocity){}
void down(int i){}
}
Java中没有C++中析构函数的概念。析构函数是一种在对象被销毁时可以被自动调用的函数。
在清理方法中,还必须注意对基类的清理方法和成员对象清理方法的调用顺序,以防止某个对象依赖于另一个子对象情形发生。首先,执行类的所有特定的清理动作,其顺序同生成顺序相反。然后,调用基类的清理方法。
一旦涉及垃圾回收,能够信赖的事就不会很多了。垃圾回收器可能永远也无法被调用,即使被调用,它也可能以任何它想要的顺序来回收对象。最好的办法是除了内存外,不能依赖垃圾回收器去做任何事。如果需要进行清理,最好事编写自己的清理方法,但不要使用finalize()。
如果Java的基类拥有某个已被多次重载的方法名称,那么在导出类中重新定义该方法名称并不会屏蔽在基类中的任何版本。无论是在该层的基类中对方法进行定义,重载机制都可以正常工作。
当你想要覆写某个方法时,可以使用@Override这个注解。它可以防止你在不需要进行重载时意外进行了重载。
组合和继承都允许在新的类中放置子对象,组合是显式的这样做,而继承是隐式的做。
组合技术通常用于想在新类中使用现有类的功能,但新类的用户看到的只是为新类所定义的接口,而非所嵌入对象的接口。
对于任何继承于此类的导出类或其他任何位于同一包内的类来说,它是可以访问的。
将导出类转换成基类。
导出类是基类的一个超集,它可能比基类含有更多的方法,但它必须至少具备基类中所含有的方法。
该用组合还是继承,一个最清晰的判断办法就是是否需要从新类向基类进行向上转换。
final可以用于三种情况:数据、方法、类
使数据恒定不变是有用的:
在编译期常量这种情况,编译器可以将该常量值带入任何可能用到它的计算式中,也就是可以在编译时执行计算式,这就减轻了运行时的负担。在对这个常量进行定义时,必须初始化。
一个是static又是final的域只占据一段不能改变的存储空间。
对于对象引用,final引用恒定不变,对象自身可以被修改。
Java允许生成"空白final",空白final指被声明为final但又未给定初始值的域。无论什么情况,编译器都确保final在使用前必须被初始化。
public class BlankFinal {
private final int i=0;
private final int j;//必须进行初始化
private final Poppet p;
public BlankFinal(){
j=1;
p=new Poppet(1);
}
public BlankFinal(int x){
j=x;
p=new Poppet(x);
}
public static void main(String[] args){
new BlankFinal();
new BlankFinal(2);
}
}
class Poppet{
private int i;
Poppet(int ii){
i=ii;
}
}
Java允许在参数列表中以声明的方式将参数指明为final,这就意味着你无法在方法中更改参数引用所指向的对象。
public class FinalArguments {
void with(final Gizmo g){
//g=new Gizmo();不能赋值。
}
int without(final int i){
//i+=1;不能改变
return i+1;
}
}
class Gizmo{
public void spin(int i){
System.out.println(i);
}
}
使用final方法的原因有两个:
private方法都隐式的指定是final。
当将某个类整体定义为final时,就表面此类不能被继承。
在对导出类进行加载时,会先对基类进行加载。如果该基类还有自身的基类,那么第二个基类就会被加载。
标签:垃圾 编译器 自身 pac ring 隐式 析构函数 extends 转型
原文地址:https://www.cnblogs.com/Tan-sir/p/11228965.html