首页 > 其他 > 详细

第七章 复用类

时间:2020-11-27 19:30:25      阅读:48      评论:0      收藏:0      [点我收藏+]

复用类的关键在于使用类但是不破坏现有代码。

7.1 组合语法

1、toString方法

每一个非基本类型的类都应该有一个这样的方法。

当编译器需要一个String而自己只有一个对象的时候,这个方法就会得到调用。

2、引用初始化的四个位置

(1)在定义对象的地方。

private String s = "Hello World!"

(2)在类的构造器中。

public Bath(){
		s1 = "a";
		s2 = "b";
}

(3)惰性初始化。

public String toString(){
		if(s3 == NULL){
				s3 = "c";
		}
}

(4)使用实例初始化。

{
		s4 = "d";
}

7.2 继承语法

继承在Java中总是存在的,要么是显式继承了自己写的类,要么是隐式继承了标准根类Object。

访问权限在继承中很重要,如果对类不加public,那么其默认是包继承权限。

而对域和方法,推荐把所有的域设置为private,方法设置为public。

子类会继承父类的public、protected成员,同一包内会继承friendly成员,不可能继承private成员。

子类会继承规则允许的方法,但是同时子类也可以自己重写这些方法,或者添加一些方法。

7.2.1 初始化基类

1、继承不只是复制基类的接口。

当创建了一个导出类的对象时,该对象包含了一个基类的子对象。

基类在导出类构造器可以访问它之前,就已经完成了初始化。

class Art{
    Art(){
        System.out.println("Art Constructor has been used.");
    }
}

class Drawing extends Art{
    Drawing(){
        System.out.println("Drawing Constructor has been used.");
    }
}


public class Cartoon extends Drawing{
    Cartoon(){
        System.out.println("Cartoon Constructor has been used.");
    }

    public static void main(String[] args){
        Cartoon test = new Cartoon();
    }
}

输出结果为:技术分享图片

2、带参数的构造器。

我们必须使用super关键字来显示地调用基类的关键字。

这也是我们在子类构造器中首先要做的。

7.3 代理

1、其实我觉得这一部分可以参见《大话设计模式》的代理部分来看,还是挺简单易懂的。

婷婷、戴笠、左嘉庄三个人之间的故事。左嘉庄和戴笠两个人做的事情是一模一样的,也就是他们有相同的接口,但二者又不是继承关系。

2、代理是继承和组合的中庸之道。

3、代理的用处:远程代理、虚拟代理、安全代理、智能指引。

7.4 结合使用组合和继承

继承要注意初始化哦。

7.4.1 确保正确处理

1、许多情况下,清理不是问题。

2、我其实不想在这块费很多功夫,因为我对Java的需求现在是能实现我的功能,垃圾处理显得不是很重要,或许说过段时间自己在看JVM虚拟机的时候这段才是重点。

3、继承类的垃圾处理和利用构造器的初始化的顺序是不同的。

应该是先对子类使用垃圾处理,然后再对其中包含的基类的对象垃圾进行处理。

7.4.2 名称处理

1、在Java中其实不用担心名字重复这个事情,Java已经帮我们做的很好了。

2、重载与重写。

3、这个注解是来帮助我们一定来进行重写的,如果我们重载的话编译器会报错的。

@Override

7.5 在组合和继承之间选择

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

2、组合通常用于想在新类中使用其子对象而非使用接口的情况。

3、继承则主要用于为某个类开发特定版本。

7.6 protected

我们还是推荐把基类中的域全部设置为private。

7.7 向上转型

1、继承更多的是用来表示逻辑关系。

7.7.1 什么叫向上转型

从传统的类继承图来看,超类在上,子类在下。因此成为向上转型。

向上转型是从一个较专用类型转型为较通用类型,所以是比较安全的,

向上转型一般要阉割方法。

7.7.2 再论组合与继承

实际生产生活中我们是不推荐过多使用继承的。

继承的使用原则:必须要使用到向上转型。如果不是必须的话,那么就最好不要继承。

7.8 final关键字

final通常的含义:不允许改变。

final使用的三种情况:数据、方法、类。

7.8.1 final数据

1、永不改变的编译时常量(只要带上final就可以)。

static final 名称要大写。

2、不希望这个数据改变可以用final。

3、空白final:无论什么情况,编译器都令空白final在使用前被初始化。

4、final参数:当基本类型的参数被声明final时:你可以读取数据,但是你没办法改变数据。

7.8.2 final方法

1、第一层原因:锁定方法,不允许任何继承类修改它的含义。

不是不让用,只是不让改。

2、二、效率问题:这是因为很早之前的问题了,现在编译器和虚拟机能帮助我们解决掉这些问题。

3、类中所有的private方法都被隐式地指明了是final方法。

7.8.3 final类

1、含义:不希望与任何子类继承他。

2、final类中所有的方法都是隐式地声明为final的。

7.8.4 对于final的一些忠告

主要是说要不要将方法标记为final啊。

标记final的意思是不希望有人来继承我的方法,但其实有的人继承了这些方法能干很多事情的。

7.9 初始化及类的加载

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

7.9.1 继承与初始化

运行时,先访问main函数。

加载器开始启动并找出该类的编译代码。

加载时,由于extends知道有一个基类,于是加载基类。

直到所有的基类加载完毕。

很重要的一点是static方法是在加载类的时候就被执行了。

所有的类加载完毕。开始创建对象。

对象中所有的基本类型会被设置为默认值。

然后调用构造器。(注意,基类构造器会在构造器中优先执行。)

class Insect{
    private int i = 9;
    protected int j;
    Insect(){
        System.out.println("i = " + i + "    j = " + j);
        j = 39;
    }

    private static int x1 = printInit("static Insetc.x1 initialized");

    static int printInit(String s){
        System.out.println(s);
        return 47;
    }
}


public class Beetle extends Insect{
    private int k = printInit("Beetle.k initialized");

    public Beetle(){
        System.out.println("k = " + k);
        System.out.println("j = " + j);
    }

    private static int x2 = printInit("static Beetle.x2 initialized");

    public static void main(String[] args){
        System.out.println("Beetle Constructor");
        Beetle b = new Beetle();
    }

}

Result:技术分享图片

7.10 总结

1、继承和组合都能从现有类型生成新的类型。

组合复用类,继承复用接口。

2、优先选择组合。设计向上转型的时候选择继承。

3、在设计一个系统的时候,我们的目标应该是找到或者创建某些类,每个类都有具体用途,都能承担功能。

4、把项目当做有机体去培养,去孕育,付出时间和精力来不断进行优化。

不要只是说能做出来就行。

第七章 复用类

原文:https://www.cnblogs.com/xrzhang/p/14049649.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!