复用代码是Java众多引人注目的功能之一,但要想成为极具革命性的语言,仅仅能够复制并加以改变是不够的。它还必须能做更多的事情。在Java中问题的解决都是围绕着类展开的,可以通过创建新类来复用代码,而不必从头开始编写。可以使用别人已开发调试好的类。
通过创建新类来复用代码的窍门在于使用类而不破坏现有程序代码:
方法一:只需在新的类中产生现有类的对象。新的类由现有类的对象组成,这叫组合,该方法只是复用了现有代码的功能,而非它的形式。
方法二:按照现有类的类型来创建新类,无需改变现有类的形式,采用现有类的形式并在其中添加新代码,这叫继承。
1.1 组合语法的使用
对于组合语法的使用,只需将对象引用置于新类中即可:
class Test{
private String s;
Test(){
System.out.println(“Test()”);
s=“Constructed”;
}
public String toString(){
return s;
}
}
public class Thinking_test {
private String value1,value2,value3,value4;
private Test t=new Test();
private int i;
private float f;
@Override
public String toString() {
return “Thinking_test{” +
“value1=’” + value1 + ‘’’ +
“, value2=’” + value2 + ‘’’ +
“, value3=’” + value3 + ‘’’ +
“, value4=’” + value4 + ‘’’ +
“, t=” + t +
“, i=” + i +
“, f=” + f +
‘}’;
}
public static void main(String []args){
Thinking_test test=new Thinking_test();
System.out.println(test);
}
}
Output:
【一线大厂Java面试题解析+后端开发学习笔记+最新架构讲解视频+实战项目源码讲义】
浏览器打开:qq.cn.hn/FTf 免费领取
Test()
Thinking_test{value1=‘null’, value2=‘null’, value3=‘null’,
value4=‘null’, t=Constructed, i=0, f=0.0}
这里有一个特殊的函数:toString()。每一个非基本类型的对象都有一个toString()方法,而且当编译器需要一个String而你却只有一个对象时,该方法便会被调用。
1.2 引用的初始化
编译器并不是简单地为每一个引用创建默认对象,同时在初始化引用时可以在代码中的以下位置进行:
1.在定义对象的地方
,这意味着它们总是能够在构造器被调用之前被初始化。
2.在类的构造器中
3.就在正要使用这些对象之前
,这种方式称为:惰性初始化。在生成对象不值得及不必每次都生成对象的情况下,这种方式可以减少额外的负担。
4.使用实例初始化
如果没有在定义处初始化,那么除非发生了不可避免的运行期异常,否则将不能保证信息在发送给对象引用之前已经被初始化。
2.1 继承语法
当创建一个类时总是在继承,因此,除非已明确指出要从其他类中继承,否则就是隐式地从Java的标准根类Object进行继承。组合的语法比较平实,但是继承使用的是一种特殊的语法。在继承过程中,需要先声明“新类与旧类相似”。这种声明通过在类的左边花括号之前,书写后面紧跟基类名称的关键字extends而实现。这样做,会自动得到基类种所有的域和方法
。
2.2 初始化基类:
继承类从外部看,就像是一个与基类具有相同接口的新类,或许还会有一些额外的方法和域。但继承并不只是复制基类的接口。当创建了一个导出类的对象时,该对象包含了一个基类的子对象。这个子对象与你用基类直接创建的对象是一样的。二者的区别在于,后者来自于外部,而基类的子对象被包装在导出类对象内部。
仅有一种方法来保证基类子对象的正确初始化:在导出类构造器中调用基类构造器来执行初始化,而基类构造器具有执行基类初始化所需要的所有知识和能力。
Java会自动在导出类的构造器中插入对基类构造器的调用:
class Art{
Art(){
System.out.println(“Art”);
}
}
class Drawing extends Art{
Drawing(){
System.out.println(“Drawing”);
}
}
public class Cartoon extends Drawing{
public Cartoon(){
System.out.println(“Cartoon”);
}
public static void main(String[] args) {
Cartoon cartoon=new Cartoon();
}
}
Output:
Art
Drawing
Cartoon
构建过程是从基类“向外”扩散的,所以基类在导出类构造器中可以访问它之前,就已经完成了初始化。即使没有给Cartoon()创建构造器,编译器也会自动合成一个默认的构造器,该构造器将调用基类的构造器。
使用组合和继承是很常见的事,通过使用组合和继承可以创建比较复杂的类。
3.1 名称屏蔽
若Java的基类拥有某个已被多次重载的方法名称,那么在导出类中重新定义该方法名称并不会屏蔽其在基类的任何版本。因此,无论是在该层或者它的基类中对方法进行定义,重载机制都可以正常工作
。
class Homer{
char doh(char c){
System.out.println(“doh(char)”);
return ‘c’;
}
float doh(float f){
System.out.println(“doh(float)”);
return 1f;
}
}
class MilHouse{};
class Bart extends Homer{
void doh(MilHouse m){
System.out.println(“doh(MilHouse)”);
}
}
public class Hide {
public static void main(String[] args) {
Bart b=new Bart();