zoukankan      html  css  js  c++  java
  • 类再生(合成、继承、final)

    类再生

    有两种方法达到代码复用的效果:合成、继承。

    合成的语法

    合成就是形成对象,把复用的代码置入对象句柄。

    在类内字段使用基本数据会初始化为零,但对象句柄会初始化为null。在下面的程序中若没有new该对象,s初始化为null。

    class WaterSource {
    	private String s;
    	WaterSource() {
    		System.out.println("WaterSource()");
    		s = new String("Constructed");
    	}
    	public String toString() { return s; }
    }
    

    如希望句柄得到自己定义的初始化,可在下面地方进行:

    1. 在对象定义的时候。这意味着它们在构建器调用之前肯定能得到初始化。
    2. 在那个类的构建器中。
    3. 紧靠在要求实际使用那个对象之前。这样做可减少不必要的开销——假如对象并不需要创建的话。

    继承的语法

    含有自变量的构造器

    如果构造器中含有自变量,必须明确编写对基础类的调用代码。

    class Game {
    	Game(int i) {
    		System.out.println("Game constructor");
    	}
    }
    class BoardGame extends Game {
    	BoardGame(int i) {
    		super(i);
    		System.out.println("BoardGame constructor");
    	}
    }
    

    捕获基本构造器的违例

    编译器会防止衍生类构建器捕获来自基础类的任何违例事件。显然,这有时会为我们造成不便。

    public class A {
        public A() throws Exception{
                throw new Exception("基类报错信息。。。");
        }
    
        public A(String s){
            System.out.println("A s:" + s);
        }
    }
    
    class B extends A{
        public B() throws Exception {
                super();
        }
    
        public B(String s){
            super(s);
            System.out.println("s : " + s);
        }
    
        public static void main(String[] args) {
            try{
                B b = new B("111");
            } catch (Exception e) {
                e.printStackTrace();
            }
    
        }
    }
    

    在上面的程序中,若导出类B没有明确调用A的某个构造器,则会默认调用基类A的默认构造方法;如果B的带参构造器中public B(String s)没有显示调用 super(s);,则会调用A的默认构造器,这时A的默认构造器抛出异常,B的默认构造器里不能捕获基类A构造器中抛出的异常,需直接抛出,像这样public B(String s) throws Exception{,如果上面程序中B的带参构造器调用的是基类A的默认构造器,那B的带参构造器也需要抛出异常。

    protected

    protected本身是私有的,但是可由这个类的子类或同包内的任何东西访问。

    累积开发

    继承的一个好处是它支持“累积开发”,允许我们引入新的代码,同时不会为现有代码造成错误。我们可保持现有代码原封不动(另外有人也许仍在使用它),不会为其引入自己的编程错误。一旦出现错误,就知道它肯定是由于自己的新代码造成的。

    请注意,继承是对一种特殊关系的表达,意味着“这个新类属于那个旧类的一种类型”。

    上溯造型(向上转型)

    向上转型

    向上转型是安全的,因为衍生类的方法要比基类的多,向上转型只是丢掉了衍生类中的方法,保留基类的方法。但是其表现的行为还是衍生类的行为,这就是行为的正确性。

    合成与继承的结合

    确保正确的清除

    有些类必须写一个特别的方法,明确的做清理的工作,比如io操作,有close方法。

    一般在try中使用,在finally中执行清理。像这样:

    CADSystem x = new CADSystem(47);
    try {
    	// Code and exception handling...
    } finally {
    	x.cleanup();
    }
    

    不能指望知道垃圾收集何时开始。除了内存的回收外,其他任何东西最好不要依赖垃圾收集器进行回收,需要制作自己的清理方法。也不要依赖finalize()

    理解java中的finalize()

    • finalize()是Object的protected方法,子类可以覆盖该方法以实现资源清理工作,GC在回收对象之前调用该方法。
    • finalize()与C++中的析构函数不是对应的。C++中的析构函数调用的时机是确定的(对象离开作用域或delete掉),但Java中的finalize的调用具有不确定性
    • 不建议用finalize方法完成“非内存资源”的清理工作,但建议用于:① 清理本地对象(通过JNI创建的对象);② 作为确保某些非内存资源(如Socket、文件等)释放的一个补充:在finalize方法中显式调用其他资源释放方法。

    如何理解合成和继承?

    比如汽车和车辆的关系,汽车并不“包含”车辆;相反,它“属于”车辆的一种类别。而轮子,车门,车灯等可以组合成一辆汽车。“属于”关系是用继承来表达的,而“包含”关系是用合成来表达的。

    final关键字

    意思是:声明“这个东西(数据、方法、类)不会变”。

    final数据

    final若作用于基本数据类型代表“常数”,主要应用于两方面:

    1. 编译期常数,它永远不会变

    2. 在运行期初始化一个值,我们不希望它发生变化

      在编译期的常数,程序可将常数值“封装”到计算过程中,可在编译期执行,从而节省运行时的开销。

    若final作用于对象句柄,则句柄值初始化到一个具体的对象。而且永远不能将句柄指向另一个对象。

  • 相关阅读:
    【译文】HTML5 Canvas的点击区域检测以及如何监听Canvas上各种图形的点击事件
    快速排序法精简理解
    数据结构--堆
    数据结构--哈希表
    数据结构--队列
    数据结构--栈
    数据结构--数组
    数据结构--链表
    算法的基本知识
    Arthas
  • 原文地址:https://www.cnblogs.com/sean-zeng/p/11053188.html
Copyright © 2011-2022 走看看