代码的复用:组合和继承
组合的概念:new一个对象,并且引用改对象的属性或方法,复用的是代码的功能。
继承的概念:extends父类,采取现有类的形式对新类进行改造。
以上两种方法都可以很好的对代码进行复用,避免代码冗余。
组合的例子:
public class Test1 {
private String s;
Test1(){
System.out.println("Test1()");
s = new String("Constructed");
}
public String toString(){
return s;
}
public void zuHeFunction(){
System.out.println("组合方法");
}
}
public class TestMain {
private String s1 = new String("Happy New Year");
private String s2 = "Happy New Year";
private String s3, s4;
static Test1 t1;
Test1 t2;
Test1 t3;
int i;
float j;
public TestMain() {
System.out.println("TestMain()");
s3 = new String("Joy");
i = 3;
j = 3.14f;
t1 = new Test1();
}
void print(){
if(s4==null){
s4 = new String("Joy");
}
System.out.println("s1:"+s1);
System.out.println("s2:"+s2);
System.out.println("s3:"+s3);
System.out.println("s4:"+s4);
System.out.println("i:"+i);
System.out.println("j:"+j);
System.out.println("t1:"+t1);
}
public static void main(String[] args) {
TestMain testMain = new TestMain();
testMain.print();
Test1 t3 = new Test1();
t1.zuHeFunction();
t3.zuHeFunction();
}
public void f1(){
t2.zuHeFunction();
}
}
在MainTest类的main方法中,创建了一个Test1对象,然后调用Test1类中定义的zuHeFunction()。这就是代码的组合。
以上代码中需要注意的几点:
1、代码加载的时候最先加载static代码,如果不在main方法中重新定义一个t3,则会报//Cannot make a static reference to the non-static field t3
因为在加载main之前,只加载了static Test1 t1;
2、toString方法:
因为它是Object里面已经有了的方法,而所有类都是继承Object,所以“所有对象都有这个方法”。
它通常只是为了方便输出,比如System.out.println(xx),括号里面的“xx”如果不是String类型的话,就自动调用xx的toString()方法。
总而言之,它只是sun公司开发java的时候为了方便所有类的字符串操作而特意加入的一个方法
所以打印出的对象,是一组字符串。
输出结果:
TestMain()
Test1()
s1:Happy New Year
s2:Happy New Year
s3:Joy
s4:Joy
i:3
j:3.14
t1:Constructed
Test1()
组合方法
组合方法
继承的例子:
继承关键字:extends
所有的类都继承java.lang.Object
执行程序的时候,先执行父类,再执行子类。(先有爸爸再有儿子)。这里的父类不仅指本身继承的类,而是指其上的所有的父类。
super指的是指向自己超类的指针,这个超类指的是离自己最近的父类。
三大用法:
super.属性 //超类的属性
super.方法() //超类的方法
super(); //超类的构造方法
public class Extends1 {
public int k = 1;
static{
System.out.println("Static Extends1");
}
public Extends1() {
System.out.println("Extends1()");
}
public void f1(){
System.out.println("f1()");
}
public int f11(int i){
++i;
System.out.println(i);
return i;
}
public void fk(){
k=111;
}
}
public class Extends2 extends Extends1{
static{
System.out.println("Static Extend2");
}
public Extends2(){
System.out.println("Extends2()");
}
public Extends2(String i){
System.out.println("Extend2(String)");
}
public Extends2(int i){
System.out.println("Extend2(i)");
}
public void f2(){
System.out.println("f2()");
}
}
public class MainTest extends Extends2 {
private int i=10;
private int k=0;
static{
System.out.println("Static MainTest");
}
public MainTest(){
super(1); //super构造方法(指定调用父类的哪个构造方法,运用于父类有多个构造方法时指定调用,如果没有写则调用父类默认的无参构造方法,如果父类没有定义则编译报错)
System.out.println("MainTest()");
}
public static void main(String[] args) {
MainTest mainTest = new MainTest();
mainTest.test();
}
public void test(){
int j = super.f11(i); //super方法
super.fk(); //super方法
System.out.println("i:"+i);
System.out.println("j:"+j);
System.out.println("k:"+super.k); //super属性
System.out.println("k:"+k); //super属性
}
}
输出结果:
Static Extends1
Static Extend2
Static MainTest
Extends1()
Extend2(i)
MainTest()
11
i:10
j:11
k:111
k:0
输出结果分析:
1、子类继承父类,程序执行顺序,先父类再子类;
2、静态方法在程序加载之前完成,所以前三个按照父类到子类的静态方法先打印出来;
3、new MainTest(),从父类到子类执行构造方法,在子类super(1)指定了引用父类带int类型参数的构造方法,所以是Extend2(i)。如果去掉supert(1)则默认调用父类默认的无参构造方法Extend2()。如果去掉super(1),且父类没有定义默认的无参构造方法Extend2(),则编译报错。
4、super的使用有三种场景,super.属性;super.方法;super()构造方法。
什么时候用继承,什么时候用组合?
详细的涉及设计模式,这里简单解释:
继承:is a 是不是关系 强耦合 比如女人是人,男人是人,这是继承
组合:has a 有没有 高聚合低耦合 比如需要用到某个对象的某个方法,则直接new一个对象,引用该方法即可,本身没有很大的关联性,只是你刚好有,我刚好用到的关系。
接口:can do 能不能,接口约束的是行为。
使用优先级考虑,如果继承和组合都可以,则可根据实际情况,优先考虑组合。
详细的涉及模式后面再学。
继承相关的类型转换:
上塑造性:
就是向上转型,按照类继承图的画法,一般父类是在最上面的,所以当子类向父类转型的时候,就是向上转型。向上转型对丢失一些特性的东西,所以不需要强制转换类型。
Person person() = new Women();
向下转型:
向下转型是大类变成的小类,有一些特性的东西没办法明确,所以是不安全的,需要进行强制转型,否则编译器报错。
Women women = (Women)new Person();
public class Person {
}
public class Women extends Person{
public static void main(String[] args) {
Women women = (Women) new Person(); //向下转型,需要强制转换类型
Person person = new Women();//向上转型
}
}
程序的执行过程:
加载=》初始化(区分默认初始化和初始化是不同的)=》正式执行程序