在编程中,复用代码是一件非常重要的事情,在java语言中,复用代码通常有两种方式:
第一种是在新类里面产生需要调用的类的对象,然后通过对象来调用调用类的成员和方法,这种方式叫做组合。
第二种是在现有类的基础上面,创建新类,而且不需要改变现有类,只需要要在现有类的基础上拓展出新类,这种方式叫做继承。
组合

组合方式非常简单,只需要把需要的对象引用放到新类里面就可以了。但是在新类里面,如果需要用到其他类的对象,必须将这个类的引用放到新的类里面,但是基本类型可以直接定义。
我们来看一个示例:
class W {
private String s;
W() {
System.out.println(“W()”);
s = “SSSS”
}
public String toString() { return s;}
}
public class S {
private String v1, v2;
private W w = new W();
private int I;
public String toString() {
return
“v1 = ” + v1 + ” ”+
“v2 = ” + v2 + ” ”+
“I = ” + I + ” ”+
“w =” + w;
}
}
public static void main(String[] args) {
S s = new S();
System.out.println(s);
}
/*Output:
W()
v1 = null v2 = null
I = 0 s = SSSS
上面这个示例中,我们可以看出,两个类里面都有一个toString()方法,这个方法是编译器需要String类型的时候会调用它来输出类信息。比如:“w =” + w;这句代码中,一个String对象和一个非基本类型对象相加时,编译器就会将s这个对象转为String类型,也就是调用toString()方法。
我们之前了解到,如果一个对象引用不被初始化,那么它默认为null,如果你要用这个引用调用某个对象的方法,那么就会报异常,但是从上面这个例子我们可以看出,我们可以依然可以把这个null打印出来,而且不会报异常。

初始化有四种方式:
1、 定义对象的时候,就初始化,这种很常用
2、 在构造器里面初始化
3、 先定义对象,不初始化,等到用这个对象的时候,再进行初始化,这种叫做多行初始化
4、 在方法里面进行初始化,通过调用方法从而进行初始化,这种方式叫做实例初始化。
继承
和其他oop语言一样,继承也是JAVA语言中非常重要的一部分,JAVA语言中,默认所有类都是继承Object。
继承是通过extends关键字来实现的,如果子类继承基类,子类就会获得基类所有的域和方法属性。

继承的示例如下:
class F {
private String ss = “F”;
public void append(String aa) { ss +=aa;}
public void dilutes() {append(“ dilutes()”); }
public void applys() {append(“ applys()”); }
public void scrubs() {append(“ scrubs()”); }
public String toString() {return ss;}
public static void main(String[] args) {
F f = new F();
f.dilutes();
f.applys();
f.scrubs();
print(f);
}
}
public class D extends F {
public void scrubs () {
append(“ Detergent. scrubs”);
super. scrubs ();
}
public void f() { append(“ f() ”); };
public static void main(String[] args) {
D d = new D();
d.dilutes();
d.applys();
d.scrubs();
d.f();
print(f);
print(“Testing”);
F.main(args);
}
}
/*Output:
F dilutes()
上面这个示例我们可以看出,通过append关键字将几个方法的名称链接到一块,而且基类和子类都含有main(),这样就非常有利于进行单元测试。而且为了数据方便继承和安全性结合,一般将数据成员设置为private,将方法设置为public,特殊情况时,会有调整。
其中的super关键字意识是超类,也及时说当前的这个类是继承自超类,一般使用superscrubs()这个语法来调用超类的scrubs方法。其中当前类可以称为子类或者导出类,导出类可以添加新的方法,比如:f();
当我们创建一个导出类的对象时,其实导出类的对象就相当于包含了一个基类的对象。
对于无参构造器的基类,导出类初始化时,首先会通过基类的构造器进行基类的初始化工作,然后才进行导出类的初始化工作,我们来看一个例子就明白了。
class A {
A() { print(“A”); }
}
class B extends A{
B() { print(“B”); }
}
public class C extends B{
public C() { print(“C”); }
public static void main(String[] args) {
C c = new C();
}
}
/*Output:
A
B
C
那么对于带参数的基类构造器,如果需要调用的话,就需要通过super关键字显示调用基类构造器来实现,我们来看一下下面这个例子,就明白了:
class A {
A(int a) { print(“A”); }
}
class B extends A{
B(int b) {
super(i);
print(“B”);
}
}
public class C extends B{
public C() {
super(11);
print(“C”);
}
public static void main(String[] args) {
C c = new C();
}
}
/*Output:
A
B
C