复用代码的两种方法:组合和继承

组合方法:(新类中产生现有类的对象)

  没什么好说的,就是调用别类的对象而已

  值得一提的是一个特殊方法:toString()当需要一个String却只有对象时能够自动调用此方法(每个类只需写一个toString方法)

    例如:class Myclass{

        /*..............*/

        private String s;

        public String toString(){

          return s;} }

  对象引用的初始化方法:1.定义对象之时即初始化  2.在类的构造器中初始化  3.在使用对象之前才初始化  4.实例初始化

  

 class Soap {
public Soap() {
System.out.println("Soap");
} @Override
public String toString() {
return "Constructed";
}
} public class TestInit {
private String s1 = "Happy"; // 定义初始化
private Soap s2;
private String s3, s4; // 实例初始化
{
s2 = new Soap();
} public TestInit() {
s3 = "Good"; // 构造器初始化
} @Override
public String toString() {
s4 = "Girl"; // 惰性初始化
return "TestInit{" + "s1='" + s1 + ", s2=" + s2 +
", s3='" + s3 + ", s4='" + s4 + '}';
} public static void main(String[] args) {
TestInit ti = new TestInit();
System.out.println(ti);
}
}
/*
Output:
Soap
TestInit{s1='Happy, s2=Constructed, s3='Good, s4='Girl}
*/

继承方法:(按照现有类的类型创建新类)

  除非指明要继承的类,否则隐式地从根类Object进行继承

  例如:public class Detergent extends Cleaner{/*...................*/}类Detergent继承自类Cleaner,获得Cleaner的全部域和方法

  通常为了继承,将所有基类的数据成员定义为private,将所有方法定义为public(或protected)

  想要调用基类的方法,使用super关键字super.funcFromBase();

  调用继承类对象的同时不仅调用了自己的构造器,也调用了基类的构造器(而且是在调用自己的构造器之前)

    如果基类的构造器带有参数,调用基类的构造器需要使用super:

    例如:class Base{

        Base(int i){/*...............*/} }

       class Myclass extends Base{

        Myclass(int i){

        super(i);

        /*...................*/} }

介乎组合和继承之间还存在一种方法:代理(在自己的类中建立别类的对象,在自己的方法中调用对象的方法)

  例如://在类的域中

     Baseclass bc = new Baseclass();

     void Myfunc(){

      bc.Myfunc();}

     /*.............*/

  使用代理的好处是我们可以控制使用“基类”的部分成员而不用全盘“拿来主义”

其中一种清理方式是try-finally语句组合(即使需要手动清理,也不要使用finalize())

  try{

  //需要被特殊处理的代码}

  finally{

  //不管怎样,只要try语句块内代码执行完成就会调用的代码}

不同于c++:继承类重新定义基类的某个多次重载的方法,不会屏蔽该方法在基类中的任何一个版本

@override注解:想要覆写某个方法却不小心重载了该方法时,编译器会生成一条错误信息

覆写:方法名和参数列表都完全一致  重载:方法名一致但是参数列表不同

如果是“是一个”的关系,应当使用继承(实际上慎用继承是明智的选择,如果不是必须向上转型,那么继承则不是必要的);

如果是“有一个”的关系,应当使用组合(组合在一般情况下在新类中应使调用对象域为private)

向上转型

  其中一例是在继承类中的对象作为参数可以使用基类中的方法(虽然基类中的方法的参数并非继承类中的对象类型,却可以使用)

  例如:class Base{

      play(Base bs){/*.................*/} }

     public class Son extends Base{

      Son sn=new Son();

      Base.play(sn);}这里将子类引用转换为基类引用

final关键字:(类比c++中的const关键字)

  编译期常量,这类常量必须是基本数据类型而且以final修饰

  对象引用可以是常量,也就是说永远只指向同一对象(但是指向的对象的值是可以改变的,Java并不提供任何使对象恒定不变的途径)

  同时以static和final修饰的只占有一份不变空间的常量,其名称全部大写并以_分隔单词

  使用final参数意味着无法在方法中改变参数引用所指向的对象,也无法改变基本数据的值:

    void func(final Myclass mc){

      //! mc=new Myclass(); mc因为是final修饰的,所以无权再指向新的对象

      /*...............*/}

  final方法:将方法锁定,防止继承类修改其含义

    类中所有的private方法都隐式的认为是final,如果在继承类中写一个同名的方法(并无向上引用的接口),仅仅是同名而已(与基类方法并无关联)

    只有方法是基类的接口的一部分(即能够将一个对象向上引用为基类的基本类型并调用相同方法),才能体现“覆盖”效应(无private或final的保护)

  final类:如果将类整体定义为final(例如:final class Myclass{/*..........*/}),则断绝了继承该类的途径,而且类中所有的方法都隐式指定为final

所有static对象和代码段按定义类时的书写顺序而依次初始化

类是在其任何static成员被访问时加载的(构造器是隐式的static成员)

调用一个继承类的初始化顺序:基类->(可能存在的其他基类)->继承类

  

Thinking In Java 4th Chap7 复用类的更多相关文章

  1. java编程思想-复用类总结

    今天继续读<java 编程思想>,读到了复用类一章,看到总结写的很好,现贴上来,给大家分享. 继承和组合都能从现有类型生成新类型.组合一般是将现有类型作为新类型底层实现的一部分来加以复用, ...

  2. 【Thinking in java, 4e】复用类

    mark一篇09年的<Thinking in Java>笔记:here --> https://lawrence-zxc.github.io/2009/11/07/thinking- ...

  3. java编程思想-复用类(2)

    如果java的基类拥有某个已被多次重载的方法名称,那么在导出类中重新定义该方法名称并不会屏蔽其在基类中的任何版本(这一点与C++不同) class Homer { char doh(char c) { ...

  4. java编程思想-复用类

    /* 一个文件中只能有一个public类 并且此public类必须与文件名相同 */ class WaterSource { private String s; WaterSource() { Sys ...

  5. [THINKING IN JAVA]复用类

    7 复用类 7.1 组合 即在一个类中使用另一个类作为成员变量,这是复用了现有程序代码的功能,而非形式. 7.2 继承 关键字:extends,这种复用是形式的复用,是一种可扩展和限制的复用: 复用: ...

  6. Java编程思想学习(五) 复用类

    1.继承与组合 复用类的方法有两种:继承与组合.继承就不多说了,组合就是直接在类中new一个对象. 数组也是对象,使用数组也是组合的一种. 2.初始化基类 当创建一个导出类的对象时,该对象包含一个基类 ...

  7. java复用类

    java复用类英文名叫reusing classes  ,重新使用的类,复用的意思就是重复使用的类,其实现方法就是我们平常使用的组合和继承: 1.组合: has-a 的关系  (自我理解:组合就是我们 ...

  8. Java基础 -- 复用类(组合和继承)

    复用类有两种实现方式. 在新的类中产生现有类的对象,由于新的类是由现有类的对象所组成,所以这种方法称之为组合. 采用继承实现. 一  组合语法 下面创建两个类WaterSource和Sprinkler ...

  9. 初读"Thinking in Java"读书笔记之第七章 --- 复用类

    组合语法 将对象引用置于新类中,即形成类的组合. 引用初始化方法 在定义处初始化. 在类的构造器中初始化. 在使用这些对象之前,进行"惰性初始化". 使用实例初始化. 继承语法 J ...

随机推荐

  1. python2和python3区别

    字符编码: py3中默认字符编码是unicode:py2中默认字符编码是 ASCII,如果文件中出现了中文,需要在顶部加入coding声明#coding:utf8 让用户输入:py3中直接使用inpu ...

  2. 2019-12-10:win7,win12提权练习

    一.win7 1,上传webshell到服务器,访问 2,因为win7权限没设置好,导致任何命令都可以执行 直接提权成功,还可以通过msf工具利用exp进行提权,今天太晚了就先不做了 二.win201 ...

  3. [PKUSC2018]真实排名——线段树+组合数

    题目链接: [PKUSC2018]真实排名 对于每个数$val$分两种情况讨论: 1.当$val$不翻倍时,那么可以翻倍的是权值比$\frac{val-1}{2}$小的和大于等于$val$的. 2.当 ...

  4. 《基于Python的GMSSL实现》课程设计个人报告

    <基于Python的GMSSL实现>课程设计个人报告 一.基本信息 姓名:刘津甫 学号:20165234 题目:GMSSL基于python的实现 指导老师:娄嘉鹏 完成时间:2019年5月 ...

  5. Spring boot 集成Solr

    首先安装Solr 集成 ikanalyzer ,可以参考 https://www.cnblogs.com/lick468/p/10867492.html https://www.cnblogs.com ...

  6. Redis Desktop Manager的下载及安装

    一.下载Redis Desktop Manager 1. Redis Desktop Manager 的下载路径 (1)https://pan.baidu.com/s/1Jvr9MbgFn4UJh4M ...

  7. 【Canvas】勾画调和级数Harmonic series 曲线 y=1+1/2+1/3+1/4+1/5+1/6+1/7+1/8+....

    相关资料:https://baike.baidu.com/item/%E8%B0%83%E5%92%8C%E7%BA%A7%E6%95%B0/8019971?fr=aladdin 调和级数(英语:Ha ...

  8. net start mysql 发生系统错误2 系统找不到指定的文件

    以管理员身份运行,在命令行输入cd+mySQL的bin目录的安装路径 C:\Windows\system32>cd C:\Program Files\MySQL\MySQL Server5.6\ ...

  9. mysql逻辑备份mydumper

      mydumper是一个针对MySQL的高性能多线程备份和恢复工具,它提供了并发备份功能,备份效率有很大提高. 安装mydumper yum安装 # rpm -ivh https://github. ...

  10. oracle数据库死锁原因及分析

    定义: 当两个用户希望持有对方的资源时就会发生死锁. 即两个用户互相等待对方释放资源时,oracle认定为产生了死锁,在这种情况下,将以牺牲一个用户作为代价,另一个用户继续执行,牺牲的用户的事务将回滚 ...