7 复用类

7.1 组合

即在一个类中使用另一个类作为成员变量,这是复用了现有程序代码的功能,而非形式。

7.2 继承

  1. 关键字:extends,这种复用是形式的复用,是一种可扩展和限制的复用;
  2. 复用:自动获取基类的所有public(protected)成员和方法,如果基类的成员和方法没有访问限定词,那么这个基类的无限定词方法和成员能在同一个包中的子类中访问,其它包中不行(包访问权限);
  3. 初始化基类:在子类构造器可访问之前先会调用父类的构造器,如果父类还有父类,将继续向上搜寻并调用构造器;如果不显式调用父类构造器,将调用父类的默认午餐构造器;如果不显式调用父类的构造器而父类没有默认构造器,将无法通过编译,这时需要在子类构造器中显示调用父类的某个非默认构造器;
    1. package com.chenlei.study.thinkinginjava;
    2.  
    3. import static com.chenlei.study.thinkinginjava.Print.*;
    4.  
    5. public class ClassConstructor {
    6.  
    7. public static void main(String[] args) {
    8. new C();
    9. }
    10.  
    11. }
    12.  
    13. class A{
    14. public A() {
    15. print("A constructor");
    16. }
    17. }
    18.  
    19. class B extends A{
    20. private int flag;
    21. public B(int flag) {
    22. this.flag = flag;
    23. print("B constructor");
    24. }
    25. }
    26.  
    27. class C extends B{
    28. public C() {
    29. super(0);//如果不指定调用哪个父类构造器将无法通过编译,由此可见在基类构造器被调用之前一定会调用父类构造器
    30. }
    31. }
    32. /**
    33. * output:
    34. * A constructor
    35. * B constructor
    36. */

7.3 代理

  1. Java并不直接支持代理;
  2. 如果想要复用某个类,使用成员变量组合或者使用继承都会使被复用的类所有的可访问方法都暴露出来,这时可以结合继承和组合,使用“代理”来实现部分方法的“继承”;
  3. 老板的秘书就是一个代理,想要知道老板的意思,不能从老板处”继承“,不能把老板作为”成员变量“,那么就只能通过秘书来传达通知、请求等,这样就能让员工知道该知道的,屏蔽不应该知道的;
    1. package com.chenlei.study.thinkinginjava;
    2.  
    3. public class Proxy {
    4. public static void main(String[] args) {
    5. BossProxy proxy = new BossProxy();
    6. Print.print(proxy.getEmployeeNum());
    7. }
    8. }
    9.  
    10. abstract class CompanyMember{
    11. private int age;
    12. private String name;
    13. public int getAge() {
    14. return age;
    15. }
    16. public void setAge(int age) {
    17. this.age = age;
    18. }
    19. public String getName() {
    20. return name;
    21. }
    22. public void setName(String name) {
    23. this.name = name;
    24. }
    25. }
    26.  
    27. class Boss extends CompanyMember{
    28. private double money;//不能让员工知道
    29. private int employeeNum;
    30. private int wifeNum;//不能让员工知道
    31.  
    32. Boss(double money,int employeeNum,int wifeNum){
    33. this.money = money;
    34. this.employeeNum = employeeNum;
    35. this.wifeNum = wifeNum;
    36. }
    37.  
    38. public double getMoney() {
    39. return money;
    40. }
    41. public void setMoney(double money) {
    42. this.money = money;
    43. }
    44. public int getEmployeeNum() {
    45. return employeeNum;
    46. }
    47. public void setEmployeeNum(int employeeNum) {
    48. this.employeeNum = employeeNum;
    49. }
    50. public int getWifeNum() {
    51. return wifeNum;
    52. }
    53. public void setWifeNum(int wifeNum) {
    54. this.wifeNum = wifeNum;
    55. }
    56. }
    57.  
    58. class BossProxy extends CompanyMember{
    59. private Boss boss;
    60. public BossProxy() {
    61. if(boss == null){
    62. boss = new Boss(1000d,100,3);
    63. }
    64. }
    65. public int getEmployeeNum(){
    66. return boss.getEmployeeNum();
    67. }
    68. }

由此可见,代理让一些该暴露的暴露了,不该暴露的隐藏起来,这似乎在权限管理中非常有用。虽然没看过设计模式中的代理模式,但是我觉得可以在代理方法前后包裹一些方法和操作来做特定的处理,比如springAOP、spring事务代理?或者是实现同步锁的时候在原子方法保证安全性?懒加载(spring注入)?

7.4 基类中重载

在基类中重载父类的方法是可以的,只要基类的重载方法满足方法名和父类某些方法相同,但参数列表个数、顺序、类型或返回类型不同时都是可以正常重载的,若方法名和返回类型、参数列表一模一样,将是覆盖,而不是重载。

7.5 组合和继承的区别

  1. 组合:has-a
  2. 继承:is-a

7.6 protected关键字

  1. 子类访问权限:继承自基类的子类,可以访问基类的protected域;
  2. 包访问权限:和具有protected域的类处于同一个package的类能访问该类的protected域

7.7 向上转型

一个通用的方法需要对一种类型的对象进行处理,继承的优势就显现出来了;只需要将参数设置为基类,那么任何该基类的子类都可以作为参数传入而不报错,因为编译器将把这些子类自动转型为基类,而不需要为每个子类写一个方法,便于管理和操作。

7.8 final关键字

  1. final基础数据:final基本类型必须先实例化,一旦值给定将无法改变;static 所有类对象共享此数据,可以改变,但此值只有一个,一变皆变,不必初始化;所以 final static 必须初始化,而且初始化之后是所有类对象无法改变此值,共享一个;private static final和public static final的区别是前者智能通过对象引用来调用,后者可以直接通过类名调用(访问权限不同);
  2. final引用对象:无法使用new 操作符重新赋值,也无法直接将新的引用赋值给final对象,但是可以改变引用对象的值,比如 
    1. package com.chenlei.study.thinkinginjava;
    2.  
    3. public class Final {
    4. public String string = "haha";
    5. public final String aString = string;
    6. public static void main(String[] args) {
    7. Final final1 = new Final();
    8. final1.string = "123";
    9. System.err.println(final1.aString);
    10. }
    11. }
    12. /**
    13. * output:
    14. * haha
    15. */
  3. final数据可以在声明时被初始化,也可在构造器中初始化,但是一定要在使用前得到正确的初始化;
  4. final参数:在方法参数列表中的final参数,同样的也无法被方法里的任何操作改变;
  5. final 方法:一是避免继承类修改方法的实现;二是提高效率,一旦编译器发现final方法,方法体将被直接嵌套在程序中而并非调用方法栈(若final方法体积很大,这种效率的提高将被抵消,新版本的jdk已优化这一点:当final方法体很大时,不再嵌套);
  6. private final方法:private方法本来就是无法继承的,加上final跟没加一样,但是编译器并不会报错,因为所有private方法都被隐式地声明为final;
  7. final类:final类无法继承;
  8. 类在被使用时才会加载,构造方法可以视为一个static方法,也就是说,当类的static成员被加载的时候,该类才会被加载;

[THINKING IN JAVA]复用类的更多相关文章

  1. java复用类

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

  2. java 复用类的三种方式区别 组合,继承,代理的区别

    1. 组合 : 只需在新类中产生现有类的对象 .(is - a 有一个) 新类是由现有类的对象组成. (引用初始化与作用域?) 2. 继承 : 按照现有类的类型来创造新类. (has - a 有一个) ...

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

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

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

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

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

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

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

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

  7. Java基础—复用类

    复用代码是Java众多引人注目的功能之一. 一般而言,实现代码重用java提供了两种方式:组合以及继承. 组合:新的类由现有类的对象所组成.(复用现有代码的功能,而非它的形式) 继承:按照现有类的类型 ...

  8. 《Think in Java》(七)复用类

    Java 中复用代码的方式就是复用类,复用类的方式有: 组合 继承 代理(并没有啥高深的含义,只是在使用类A前,新增了类B,让类B的每个方法去调用类A中对应的方法,也就是说类B代理了类A...不过我还 ...

  9. Java编程思想(四) —— 复用类

    看了老罗罗升阳的专訪,不由自主地佩服,非常年轻,我之前以为和罗永浩一个级别的年龄.也是见过的不是初高中编程的一位大牛之中的一个,专訪之后.发现老罗也是一步一个脚印的人. 别说什么难做,做不了.你根本就 ...

随机推荐

  1. linux安装jdk(以centos安装jdk1.7为例)

    1准备工作: 1 虚拟机一台vmware12,安装64位centos 2 oracle官网下载jdk1.7-linux-x64.rpm 3 winscp将jdk传送到linux上面 2开始安装: 1 ...

  2. 查询SQLSERVER执行过的SQL记录

    SELECT TOP 1000 --创建时间 QS.creation_time, --查询语句 SUBSTRING(ST.text,(QS.statement_start_offset/2)+1, ( ...

  3. java 多线程

    1.继承Thread类实现多线程继承Thread类的方法尽管被我列为一种多线程实现方式,但Thread本质上也是实现了Runnable接口的一个实例,它代表一个线程的实例,并且,启动线程的唯一方法就是 ...

  4. GeoHash原理解析

    GeoHash 核心原理解析       引子 一提到索引,大家脑子里马上浮现出B树索引,因为大量的数据库(如MySQL.oracle.PostgreSQL等)都在使用B树.B树索引本质上是对索引字段 ...

  5. hadoop2的高可用性

    1   hadoop2  namenode由一个节点变成两个节点,同时在线,且同时只有一个是活跃的,如果一个出了问题,另外一个立即接替:没必要配置Secondary NameNode.Checkpoi ...

  6. 【转】java中volatile关键字的含义

    java中volatile关键字的含义   在java线程并发处理中,有一个关键字volatile的使用目前存在很大的混淆,以为使用这个关键字,在进行多线程并发处理的时候就可以万事大吉. Java语言 ...

  7. ubuntu samba server 配置多用户访问

    [share] path = /home/share/ writeable = yes browseable = yes create mask = directory mask = guest ok ...

  8. 数据结构《17》---- 自动补齐之《二》----Ternary Search Tree

    一. 序言 上一篇文章中,给出了 trie 树的一个实现.可以看到,trie 树有一个巨大的弊病,内存占用过大. 本文给出另一种数据结构来解决上述问题---- Ternary Search Tree ...

  9. 后缀名“.dll .obj .lib”和“ .so .o .a”文件的区别含义

    (1) .dll .obj .lib使用在windows平台下.        .dll:动态链接库,作为共享函数库的可执行文件.        .obj:目标文件,相当于源代码对应的二进制文件,未经 ...

  10. Java的CLASSPATH,趁还没忘赶紧写点

    咳咳,睡眠不足加上年龄增长,真的赶脚记忆力不行啦. 接触Java以来,对于环境配置就是按照网上的教程,一路复制粘贴,也没啥想法; 最近决定啃啃ThinkInJava,没看两章就看到这CLASSPATH ...