《JAVA编程思想(第四版)》第七章(复用类)小结
组合语法
组合的小例子
组合很好理解,就是一个对象中的某个字段是另一个对象.
String, 就是一个对象,所以接下来就是一种组合
public class Person{
private int id;
private String name; //一个String对象name.
//getter和setter
}
当然自定义的对象也可以,这种是我们经常用到的组合语法.
class page{
int num;
String[] content;
}
public class Book {
int bId; //书的编号
String bookName; //书名
String author; //作者
page[] pages; //每个书都有很多页
//getter和setter方法
//构造器
}
组合语法很简单,但是有几个小知识点需要注意一下.
基本类型会被初始化(如int会初始化为0,boolean被初始化为false),而各个对象也是,不过他们是初始化为null,如果使用这个对象的方法,就会报错:万恶的空指针异常.如果想初始化这些对象,可以在代码的下列位置进行.
初始化问题
在定义对象的地方.
public class Person{
private int id;
private String name = "佚名"; //定义处进行初始化
//getter和setter
}
2.在类的构造器中,.(以上文的Person为例)
public class Person{
private int id;
private String name; //一个String对象name.
public Person(int id, String name) {
super();
this.id = id;
this.name = name;
}
public Person() {
//构造器初始化
name = "佚名";
}
//getter和setter
}
3,就在正常使用这些对象前,"惰性初始化"
public class Person{
private int id;
private String name; //一个String对象name.
public String getName() {
if(this.name == null) {
name = "佚名"; //使用前初始化
}
return name;
}
public void setName(String name) {
this.name = name;
}
//id的getter和setter
public static void main(String[] args) {
Person p1 = new Person();
System.out.println(p1.getName());
}
}
4.使用实例初始化
public class Person{
private int id;
private String name; //一个String对象name.
public Person() {}
//getter和setter
public static void main(String[] args) {
Person 老王 = new Person();
老王.name = new String(); //创建一个实例,[老王.name] 为这个实例的引用/句柄
System.out.println(老王.name);
}
}
继承语法.
定义:继承即使用extend关键字,如果class A extend B(A类继承了B类,那么A类将自动得到B类所有域和方法)
为了继承,一般的规则是将所有的数据成员都指定为private,将所有的方法都指定为public,当然,在特殊情况下,必须做出调整,但一般都很有用.
重载与覆写(重写)
如果子类的同名方法的参数顺序和类型在父类中包含,那么就是覆写,单纯的重名,但是参数不同,即为重载.与写在父类中的重载类似.
protected 关键字
在访问控制权限里,protected 关键字 :"类用户而言,这是private的,但对于任何继承于此类的子类或同一包内的类来说,它却是可访问的.":
尽管可以创建protected 域,但是最好的方式还是将域保持为private;你应当一直保留"更改底层实现"的权利.
final 关键字
使用范围:
- 一个用不改变的编译时常量.
- 一个在运行时被初始化的值,而你不希望它被改变.
- 不想被继承的类.
- 不想被覆写的方法.
根据惯例,既是static又是final的域用大写表示,并使用下划线分割各个单词.
static final int VALUE_PI = 3.1415926
我们不能因为某数据是final的,就认为在编译时可以知道它的值.final做的事不允许值被改变,而很多值都是运行时初始化的,所以无法得知..
final int randInt = random.nextInt(92);
无论什么情况,编译器都确保空白final在使用前必须被初始化.
final和private关键字
类中所有private方法都隐式地指定为是final的.由于无法取用private方法,所以也就无法覆盖它.
向上转型
继承最重要的方面在于表现新类与基类之间的关系.可以用"新类是现有类的一种类型"来概括.
而实现在代码层面的一个意义是:能够为这些子类们提供一套通用的模板,
也就是向上转型.即从一个专用类型向较通用类型转换
而子类中一定有基类的方法,所以,向上转型时唯一发生的事情是丢失方法,而不是获取它们.
继承与初始化
继承中有一个要点是初始化顺序问题: 当需要初始化子类时,先初始化父类,如果父类还有父类,那么先初始化父类的父类.(递归).
对象中所有的基本类型都会被设为默认值,对象引用被设为null----这是通过将对象内存设为二进制零值而一举生成的.
继承与组合
- 组合和继承都允许在新的类中放置子对象,组合是显式地这样做,而继承则是隐式的.(具体情况按逻辑处理,一般都是正确的.)
- 组合一般是将现有类型作为新类型底层实现的一部分加以复用,而继承复用的是接口.
- 如果你的设计变得过于复杂,通过将现有类拆分为更小的部分而添加更多的对象,通常会有所帮助.
- 尽管继承在多处被很多人强调,但我们仍应该慎用这一技术,在使用前一定要确信使用该技术确实有效.
代理
代理(Proxy)是一种设计模式,提供了对目标对象另外的访问方式;即通过代理对象访问目标对象.这样做的好处是:可以在目标对象实现的基础上,增强额外的功能操作,即扩展目标对象的功能.
这里使用到编程中的一个思想:不要随意去修改别人已经写好的代码或者方法,如果需改修改,可以通过代理的方式来扩展该方法举个例子来说明代理的作用:假设我们想邀请一位明星,那么并不是直接连接明星,而是联系明星的经纪人,来达到同样的目的.明星就是一个目标对象,他只要负责活动中的节目,而其他琐碎的事情就交给他的代理人(经纪人)来解决.这就是代理思想在现实中的一个例子
继承和组合都可以实现代理.