复用类

来源:互联网 发布:java 开发棋牌类游戏 编辑:程序博客网 时间:2024/05/22 04:05

复用类 其一

基本都是对于Thinking in Java这本书的学习总结,这里是复用类的第一部分,主要介绍了组合与继承的定义与基本用法。

组合语法

组合技术,简单的说就是将对象引用置于新类中。

例如:你需要某个对象,它具有一些String对象、几个基本类型数据,以及另一个类的对象。对于非基本类型的对象,必须将其引用置于新类中。

编译器并不是简单的为每一个引用都创建默认对象,如果这样做,会在许多情况下增加不必要的负担。

如果想初始化这些引用,可以在代码中的下列位置进行:

  1. 直接在定义对象的地方。这意味着它们总是能够在构造器被调用之前被初始化。
class Persion {    private String p;    Persion() {        System.out.println("Person()");        p = "Constructed";    }    public String toString() {        return p;    }}public Class School {    private String p = "Teacher";    private int i; //初始化}
  1. 在类的构造器中:
public School {    Person person = new Person();}

3.就在正要使用这些对象之前,这种方式称惰性初始化*
在生成对象不值得或是不必要每次都生成对象的情况下,这种方式可以减少额外的负担。

private String p2public String toString() {    if(p2 == null) {        p2 = "Strudent";    }    return;}

4.使用实例初始化。

{    i = 47;}

实例初始化
http://blog.csdn.net/sunling_sz/article/details/22862653

继承语法

继承是所有OOP语言和Java语言不可缺少的组成部分。当创建一个类时,总是在继承,因此,除非已明确要从其他类中继承,否则就是隐式地从Java的标准根类Object进行继承

extends:在继承过程中,首先要声明新类与旧类相似。这种生命是通过在类主体的左边花括号之前,书写后面紧随基类名称的关键字extends实现的。当这么做时,会自动得到基类中的所有方法。(我粗略的将其理解为A IS-A B,也就是 A是一个B,比如 我 是一个 人)

如果你需要在当前类中的一个方法中调用基类中的一个同名方法,为了避免产生递归,你将需要使用super关键字。如:super.eat();

在继承的过程中,你可以在导出类中添加新的方法。

初始化基类

Java会自动在导出类的构造器中插入对基类构造器的调用。

顺序是,先调用基类,再调用导出类。

对于没有定义构造器的基类,编译器也会为你合成一个默认的构造器。

class Game extends  DarkSouls {    Game() {        //super("2");        System.out.println("Game");    }}class DarkSouls {    public String characterName;    public double howManyTimesYouDied;    public double totalSouls;    public int version;    public DarkSouls() {        characterName = "Ashen one";        howManyTimesYouDied = 0;        totalSouls = 0;        //this.version = version;        System.out.println("DarkSouls");    }}public class PublicAClass {    public static void main(String[] args) {        Game game = new Game();    }}//DarkSouls//Game
带参数的构造器

如果将上述的DarkSouls()从无参构造器变为有参构造器DarkSouls(int version){}而不改变其他部分,编译将会报错,无法找到符合的构造器。此时,我们需要将上述代码中被注释掉的部分恢复,使用关键字super,显示地编写调用基类构造器的语句,并配以你所需要的参数列表

另外,调用基类构造器必须是你在导出类构造器中要做的第一件事。

代理

代理是继承与组合之间的中庸之道。

我们将一个成员置于所要构造的类中(组合),但与此同时我们在新类中暴露了该成员的所有方法(继承)。

结合使用组合和继承

1.确保正确清理

在Java中,我们习惯只是忘掉而不是销毁对象,并且让垃圾回收器在必要时释放内存。

这样做通常没有问题,但有时我们会希望在其生命周期内执行一些必需的清理活动。

因此,如果你想要某个类清理一些东西,就必须显式地编写一个特殊的方法来做这件事,并要确保客户端程序员知晓他们必须调用这一方法。

class Shape {    Shape(int i) {        System.out.println("Shape constructor");    }    void dispose() {        System.out.println("Shape dispose");    }}class Circle extends Shape {    Circle(int i) {        super(i);        System.out.println("Draw Circle");    }    void dispose() {        System.out.println("Erasing Circle");        super.dispose();    }}public class CADSystem extends Shape {    private Circle c;    public CADSystem(int i) {        super(i + 1);    c = new Circle(1);    System.out.println("Combined constructor");    }    public void dispose() {        System.out.println("CADSystem.dispose()");        c.dispose;        for(int i = lines.length - 1; i >= 0; i--)            lines[i].dispose();        super.dispose();    }    public static void main(String[] args) {        CADSystem x = new CADSystem(47);        try {            //Code and exception handling...        } finally {            x.dispose();        }    }}

关键字try下面的块是所谓的保护区,这意味着它需要被特殊处理。其中一项特殊处理就是无论try块是怎么样退出的,保护区后finally子句的代码总是要被执行的。

另外,垃圾回收器的调用永远是难以预估的,他可能永远也不会被调用,也可能按照任何顺序来回收对象。

最好的处理办法就是除了内存意外,不能依赖垃圾回收器去做任何事情。

如果需要进行清理,最好编写你自己的清理方法,但不要使用finalize().

2.名称屏蔽

@override注解可以防止你在不想重载时而意外的进行了重载

原创粉丝点击