一:为什么要有继承
我们一直都在想,如何去使用之前已经写好的代码,有一个简单的方式,那就是把之前写好的代码复制粘贴过来,但是这样做却带来了一定的弊端。因此,有两种方式可以解决这个问题。
第一种:我们可以创建一个新的类来复用代码,而不用重头编写,这个方法的诀窍在于使用类而不破坏现有的程序代码,。
第二种:我们也可以按照现有的类的类型来创建一个新的类。
而第一种方式就是组合方式,第二种方式就是集成的方式。为了方便介绍继承,在这里先介绍组合的方式,对比来看。
二:组合方式
组合的定义:就是在一个类中,创建了另外一个类的对象,用另外一个类来完成我们的功能。
具体代码演示:
首先定义A类,在A类中定义一个add方法,实现两个数的加法
package com.test;
public class A {
public int add(int a,int b){
return a+b;
}
public String toString(){
return "A对象的创建";
}
}
然后定义B类,调用A中的add方法。
package com.test;
public class B {
public static void main(String[] args) {
int a=0,b=9;
//创建A的对象,来完成a+b的功能
A a1=new A();
int c=a1.add(a, b);
System.out.println(c);
System.out.println(a1);
}
}
输出结果是:
总结,以上就是组合方式的使用,在这里我们可以看到,A和B两个类完全没有关系,在B中只是使用了A的add方法。
注意:toString()方法。当时我们输出一个类的对象时,此时输出的本来应该是字符换,但是现在却只有一个对象,那么编译器就是默认的去调用对象的toString方法。而且,我们知道在一个对象没有初始化的时候如果我们去使用这个对象,那么编译器就会报运行时错误,但是当我们用System.out.println(a1)时,仍然是可以输出一个null的值,而不会报错。
当然,编译器并不是为每一个引用都创建默认对象,因为那样的话,就会在很多情况下增加很多不必要的负担,
因此如果我们想初始化这些引用,可以在代码的下列位置进行初始化引用:
1、在一开始定义对象的地方
2、在构造器中
3、在将要使用这些对象之前,这种方式成为惰性初始化。
4、使用实例初始化。
三:继承方式
继承一般的规则:
1、将所有的数据成员都指定为private
2、将所有的方法都指定为public
3、子类可以直接使用父类中的方法。
构造方法的调用过程之前已经写了,地址在:类的初始化操作
1、带参数的构造器
先看继承方式:
首先定义一个类C,C的构造器是有参数的构造器
package com.test;
public class C {
C(int i){
System.out.println("调用了C的带参构造方式,参数是:"+i);
}
}
接下来定义一个类D,继承自C
package com.test;
public class D extends C {
D(int i) {
super(i);
System.out.println("调用了子类D的构造方法,参数是"+i);
}
public static void main(String[] args) {
D d=new D(3);
}
}
最后看结果在分析
总结:当使用默认构造器时,在子类可以默认去调用,不用使用super(i)方法,但是没有默认的构造器或者是想调用一个带有参数的构造器时,那么就必须使用super(i)显示的调用构造器,并配以适当的参数列表。
2、初始化顺序和清理顺序
看另外一篇:https://blog.csdn.net/SDDDLLL/article/details/82702801
四:继承和组合
1、组合:组合技术通常用于在新类中现有类的功能而非他的接口这种类型,新类的用户只需要看到这个调用接口即可,这个接口的具体实现不必去考虑。为此,我们需要在新类中将现有类设置为private类型,
注意:
1、为新的类提供方法并不是继承技术中最重要的原因,最重要的是表现子类和父类之间的关系。
2、向上转型是从一个专用类型向通用类型转换,所以总是很安全的。
最后,需要说明的是我们要慎用继承技术,除非我们清晰地知道子类可以向上转型为基类。