资讯专栏INFORMATION COLUMN

《Java编程思想》笔记7.复用类

ningwang / 3548人阅读

摘要:在类的构造方法中。对基类构造器的调用必须放到子类构造器的第一行。约定用大写字母下划线命名规范空白空白指被声明为但又未给定初值的域,但可以在构造方法必须在域的定义处代码块或构造器中对进行赋值。

点击进入我的博客

复用代码是Java众多引人注目的功能之一,但要成为极具革命性的语言,仅仅能够复制代码并对之加以改变是不够的,它还必须能够做更多的事情。

7.1 组合
组合语法

就是在当前类中产生现有类的对象。

toString()方法

每一个非基本类型的对象都有该方法,当编译器需要一个String但你只有一个对象时,该方法会自动调用。

初始化引用

编译器并不是简单的为每一个引用都创建对象,因为这回增加不必要的负担

在定义对象的时候初始化,这意味着在构造方法之前被调用。

在类的构造方法中。

就在正常使用这些对象之前——惰性初始化

使用实例初始化

7.2 继承

使用extends关键字实现继承

当创建一个类时总是在继承,除非明确指定从其他类继承,否则就是隐式从Object继承

继承时会自动得到基类中所有的域和方法

使用super.func()调用父类中的方法。

7.2.1 初始化基类

当创建类一个子类的对象时,该对象包含了一个基类的自对象。这个子对象与你用基类直接创建的对象是一样的。二者区别在于,后者来自于外部,而基类的子对象被包装在子类对象内部。

对基类子对象对正确初始化:在子类构造器中调用基类构造器。Java会自动在子类构造器中插入对基类构造器对调用。

编译器强制你去初始化基类,但并不代表会初始化成员对象。

带参数的构造器

如果基类没有默认的无参构造器,或者想调用一个带参数的基类构造器,就必须用关键字super显式地编写基类构造器的语句。

对基类构造器的调用必须放到子类构造器的第一行。

7.3 代理

Java并没有提供对代理对直接支持,这是继承和组合的中庸之道。

代理:将一个成员对象放置于所需要的构造的类中(像组合),但与此同时在新类中暴露该成员对象的相关方法(像继承)。

使用代理可以有更多的控制力,因为我们可以选择只暴露一个子集。

public class Test {
    TestDemo demo = new TestDemo();
    // 代理
    public void func() {
        demo.func();
    }
}

class TestDemo {
    void func() {}
}
7.4 结合使用组合和继承 7.4.1 确保正确清理

一般情况下,清理并不是问题,仅需让垃圾回收器完成该动作就行。但当必须亲自处理清理(如文件的关闭)时,就要多加小心。

因为,垃圾回收器可能永远也无法被调用,即时被调用,它是按照任何它想要的顺序来回收对象。

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

如果需要清理,就自己写一个清理方法,但不要使用finalize()。

清理语句尽量写在finally代码块中。

7.4.2 名称屏蔽

如果Java的基类已经拥有某个已被多次重载的方法,那么在子类中重新定义该方法名称并不会屏蔽其在基类中的任何版本。因此,无论是在该层或者它的基类中队方法进行定义,重载机制都可以正常工作。

可以使用@Override来表示要重写父类方法。

7.5 在组合和继承间选择

组合和继承都允许在新的类中放置子对象,组合是显式地这样做,而继承是隐式地做。

继承很重要但是并不意味着我们需要常常用他,如何判断是否应该使用继承请参照两个标准:

如果是“is-a”的关系,那就使用继承。如果是“has-a”的关系,那就使用组合。

是否需要向上转型,如果必须向上转型则必须使用继承,否则应该慎重考虑

7.6 protected关键字

在实际项目中,经常会想要将某些事物尽可能对这个世界隐藏起来,但仍允许导出类的成员访问它们。

尽管可以创建protected域成员,但最好的方式还是private,只有在真正需要的时候才使用protected关键字。

7.7 向上转型

“为新类提供方法”并不是继承技术最重要的方面,其最重要的方面是用来表现子类和基类之间的关系。

子类引用可以向上转型成为基类引用,因为派生类一定具有基类的方法。类接口唯一可能发生的事情是丢失方法,而不是获取它们。

7.8 final关键字 7.8.1 final数据
final变量

final基本数据类型:表示数据是不可变的常量

final对象引用:引用与对象的关联关系不可变,但可以对对象进行操作。

final static约定用大写字母+下划线命名规范

空白final

空白final指被声明为final但又未给定初值的域,但可以在构造方法

必须在域的定义处、static代码块或构造器中对final进行赋值。

final参数

Java允许在参数列表中将参数指明为final

修饰对象参数:意味着无法在方法中修改参数引用的对象

修饰基本类型:可以使用但无法修改此参数

7.8.2 final方法

把方法锁定,禁止继承类修改它(即不会被重写)

在JavaSE5之前,使用final可以提高效率,但目前已过时

final和private关键字

类中所有private方法都隐式的指定是final的,在private方法前添加final是没有额外意义的。

private修饰的方法,不属于基类接口一部分,他仅仅是隐藏在类中的一部分代码。因此如果你在导出类中“覆盖”了基类的private方法,其实并没有覆盖private方法,而产生了一个新方法。

7.8.3 final类

final放在class前做修饰,表明该类无法进行继承

final类中的域和普通类的域并无差别

final类隐式的将该类中所有的方法指定为final,所以在final类中给方法添加final关键词没有意义。

7.8.4 final的忠告

要考虑清楚!!!

7.9 初始化及类的加载

每个类的编译代码.class都存在于独立的文件中,该文件只在需要的使用程序代码时才会被加载。

按照父类到子类的顺序加载static变量

构造子类对象时,先构造父类对象。

public class Test extends TestParents {
    // (a) static属性
    static String staticProperty;

    // (b) 构造方法
    public Test() {
        System.out.println("Test constructor");
    }

    // (c) static代码块
    {
        staticProperty = print("Test static property");
        System.out.println("Test static");
    }
    
    // (d) 非static代码属性
    String property = print("Test property");

    public static void main(String[] args) {
        // (1):System.out.println(Test.staticProperty);
        // TestParents static property
        // null(因为static代码块中的代码要创建对象才执行)
        // (2):Test test = new Test();
        // TestParents static property
        // TestParents property
        // TestParents static
        // TestParents constructor
        // Test static property
        // Test static
        // Test property
        // Test constructor
    }
}

class TestParents {
    static String staticProperty = print("TestParents static property");

    String property = print("TestParents property");

    {
        System.out.println("TestParents static");
    }

    public TestParents() {
        System.out.println("TestParents constructor");
    }

    static String print(String str) {
        System.out.println(str);
        return str;
    }
}
静态代码块和静态变量

静态变量 >> 静态代码块

代码块(注意不是静态代码块)、构造方法、非static属性

三者顺序:代码块 == 非static属性 >> 构造方法;即代码块和非static属性按照代码中顺序排序,构造函数在最后面

上述Test类的代码,反编译后的结果如下所示:

public Test()
    {
        staticProperty = print("Test static property");
        System.out.println("Test static");
        property = print("Test property");
        System.out.println("Test constructor");
    }
7.10 总结

优先选择组合和代理,必要时才使用继承。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/72176.html

相关文章

  • (CZ深入浅出Java基础)设计模式笔记

    摘要:在设计模式中,所有的设计模式都遵循这一原则。其实就是说在应用程序中,所有的类如果使用或依赖于其他的类,则应该依赖这些其他类的抽象类,而不是这些其他类的具体类。使用设计模式是为了可重用代码让代码更容易被他人理解保证代码可靠性。 这是刘意老师的JAVA基础教程的笔记讲的贼好,附上传送门 传智风清扬-超全面的Java基础 一、面向对象思想设计原则 1.单一职责原则 其实就是开发人员经常说的高...

    李昌杰 评论0 收藏0
  • Java编程思想笔记9.接口

    摘要:抽象类和抽象方法抽象方法这种方法是不完整的,仅有声明而没有方法。创建抽象类和抽象方法非常有用,因为他们可以使累的抽象性明确起来,并告诉用户和编译器打算怎样来使用它们。接口用于建立类于类之间的协议。与抽象类相同,防止客户端程序员创建该类对象。 点击进入我的博客 接口和内部类为我们提供了一种将接口与实现分离的更加结构化的方法。 9.1抽象类和抽象方法 抽象方法:这种方法是不完整的,仅有...

    JessYanCoding 评论0 收藏0
  • Java编程思想》读后总结(一)

    摘要:前言编程思想这本书,陆陆续续读了年,终于基本都浏览了一遍。每个对象对外暴露接口,程序通过对象暴露的接口向对象发送消息,获取该对象的服务能力。异常处理异常处理,为编写程序阶段提供了一种预见性的防止程序崩溃的出路。 前言 《Java编程思想》这本书,陆陆续续读了1年,终于基本都浏览了一遍。通过这本书,试图理解作者的想法,才真的体会到Java思想。感谢本书的作者,不仅讲述了java的语法,更...

    hufeng 评论0 收藏0
  • Java编程思想》读书笔记-对象导论

    摘要:而面向对象则是向程序员提供表示问题空间中元素的工具,我们将问题空间中的元素及其在解空间中的表示称为对象。为什么要把对象看作是服务提供者呢这是将问题分解为对象集合的一种合理方式。职能太多,可能会导致对象的内聚性降低。在试图将子类对象当作其基类 计算机是头脑延伸的工具,是一种不同类型的表达媒体。本文以背景性的和补充性的材料,介绍包括开发方法概述在内的面向对象程序设计(Object-orie...

    NickZhou 评论0 收藏0
  • SegmentFault 技术周刊 Vol.32 - 七夕将至,你的“对象”还好吗?

    摘要:很多情况下,通常一个人类,即创建了一个具体的对象。对象就是数据,对象本身不包含方法。类是相似对象的描述,称为类的定义,是该类对象的蓝图或原型。在中,对象通过对类的实体化形成的对象。一类的对象抽取出来。注意中,对象一定是通过类的实例化来的。 showImg(https://segmentfault.com/img/bVTJ3H?w=900&h=385); 马上就要到七夕了,离年底老妈老爸...

    李昌杰 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<