天天看點

JavaSE第十七講:繼承剖析

public class ConstructorOverload
{
	public ConstructorOverload()
	{
		System.out.println("test");
	}

	public ConstructorOverload(int i)
	{
		System.out.println(++i);
	}

	public static void main(String[] args)
	{
		ConstructorOverload col = new ConstructorOverload();


	}
}
           

執行結果:

D:\src\Lesson 1>java ConstructorOverload

test

修改上個程式:

public class ConstructorOverload
{
	public ConstructorOverload()
	{
		this(3);
		System.out.println("test");
	}

	public ConstructorOverload(int i)
	{
		System.out.println(++i);
	}

	public static void main(String[] args)
	{
		ConstructorOverload col = new ConstructorOverload();
	}
}
           

輸出結果:

D:\src\Lesson 1>java ConstructorOverload

4

test

【原因】其中this(3);語句表示要調用目前的這個類裡面的接受一個整型參數的構造方法。也就是方法ConstructorOverload(int i);是以輸出4.

修改程式将上述第三行代碼段改為如下代碼段:

public ConstructorOverload()
	{
	//	this(3);
		System.out.println("test");
		this(3);
	}
           

執行結果:

D:\src\Lesson 1>javac ConstructorOverload.java

ConstructorOverload.java:7: 錯誤: 對this的調用必須是構造器中的第一個語句

                this(3);

                    ^

1 個錯誤

【說明】:this()必須要作為構造方法的第一條語句,換句話說,this()之前不能有任何可執行的代碼。

此處修改上一講的例子如下:

public class OverloadTest
{
	public int add(int a ,int b)
	{
		return a + b;
	}

	public int add(int a, int b, int c)
	{
		System.out.println(add(1,2));
		return a + b + c;
	}

	public static void main(String[] args)
	{
		OverloadTest test = new OverloadTest();

		int result = test.add(1, 2);
		int result2 = test.add(1, 2, 3);

		System.out.println(result);
		System.out.println(result2);
	}
}
           

執行結果:

D:\src\Lesson 1>java OverloadTest

3

3

6

【說明】由語句System.out.println(add(1,2));可知重載的方法之間是可以互相調用的。

1、構造方法重載:隻需看參數即可。如果想在一個構造方法中調用另外一個構造方法,那麼可以使用this()的方式調用,this()括号中的參數表示目标構造方法的參數。this()必須要作為構造方法的第一條語句,換句話說,this()之前不能有任何可執行的代碼。

2、繼承(Inheritence):Java是單繼承的,意味着一個類隻能從另一個類繼承(被繼承的類叫做父類【基類,base class】,繼承的類叫做子類),Java中的繼承使用extends關鍵字。

public class Child extends Parent
{
	public Child()
	{
		System.out.println("child");
	}

	public static void main(String[] args)
	{
		Child child = new Child();
	}
}

class Parent
{
	public Parent()
	{
		System.out.println("parent");
	}
}
           

執行結果:

D:\src>java Child

parent

child

【說明】:main方法中執行語句Child child = new Child();時,根據前面所學new關鍵字執行過程,在執行子類的構造方法之前會先去執行父類的那個不帶參數的構造方法。簡單了解:沒有父親哪來兒子!

修改程式如下:

public class Child extends Parent
{
	public Child()
	{
		System.out.println("child");
	}

	public static void main(String[] args)
	{
		Child child = new Child();
	}
}

class Parent
{
	public Parent(int i)
	{
		System.out.println("parent");
	}
}
           

執行結果:

D:\src>javac Child.java

Child.java:4: 錯誤: 無法将類 Parent中的構造器 Parent應用到給定類型;

        {

        ^

  需要: int

  找到: 沒有參數

  原因: 實際參數清單和形式參數清單長度不同

1 個錯誤

繼續修改程式如下:

public class Child extends Parent
{
    public Child()
    {
        System.out.println("child");
    }

    public static void main(String[] args)
    {
        Child child = new Child();
    }
}

class Parent
{
    public Parent(int i)
    {
        System.out.println("parent");
    }

    public Parent()
    {
        System.out.println("no args parent");
    }
}
           

執行結果:

D:\src>java Child

no args parent

child

繼續修改上次代碼,可以對上次進行修改,用super();關鍵字。

public class Child extends Parent
{
	public Child()
	{
		super(7);
		System.out.println("child");
	}

	public static void main(String[] args)
	{
		Child child = new Child();
	}
}

class Parent
{
	public Parent(int i)
	{
		System.out.println("parent");
	}

	/*
	public Parent()
	{
		System.out.println("no args parent");
	}
	*/
}
           

執行結果:

D:\src>java Child

parent

child

【說明】:此時Java便不按規定執行父類的沒有帶參數的構造函數,而是使用super關鍵字自定義的調用父類帶參數的構造函數。

3.當生成子類對象時,Java預設首先調用父類的不帶參數的構造方法,然後執行該構造方法,生成父類的對象。接下來,再去調用子類的構造方法,生成子類的對象。【要想生成子類的對象,首先需要生成父類的對象,沒有父類對象就沒有子類對象。比如說:沒有父親,就沒有孩子】。

4.super關鍵字:super表示對父類對象的引用。注意與this的關鍵字的差別。

5.如果子類使用super()顯式調用父類的某個構造方法,那麼在執行的時候就會尋找與super()所對應的構造方法而不會再去尋找父類的不帶參數的構造方法。與this一樣,super也必須要作為構造方法的第一條執行語句,前面不能有其他可執行語句。

修改以上代碼段說明問題

public Child()
	{
	//	super(7);
		System.out.println("child");
		super(7);
	}
           

執行結果:

D:\src>javac Child.java

Child.java:4: 錯誤: 無法将類 Parent中的構造器 Parent應用到給定類型;

        {

        ^

  需要: int

  找到: 沒有參數

  原因: 實際參數清單和形式參數清單長度不同

Child.java:7: 錯誤: 對super的調用必須是構造器中的第一個語句

                super(7);

                     ^

2 個錯誤

學習一下程式:

public class InheritenceTest
{
	public static void main(String[] args)
	{
		Apple apple = new Apple();
		System.out.println(apple.name);
	}
}

class Fruit
{
	String name = "fruit";
}

class Apple extends Fruit
{

}

           

執行結果:

D:\src>java InheritenceTest

fruit

【說明】:繼承了父類的name屬性。

修改程式如下

public class InheritenceTest
{
	public static void main(String[] args)
	{
		Apple apple = new Apple();
		System.out.println(apple.name);
	}
}

class Fruit
{
	String name = "fruit";
}

class Apple extends Fruit
{
	String name = "apple";
}
           

執行結果:

D:\src>java InheritenceTest

apple

【說明】:可以對父類的屬性name進行修改。

修改程式如下

public class InheritenceTest
{
	public static void main(String[] args)
	{
		Apple apple = new Apple();
		System.out.println(apple.name);
	}
}

class Fruit
{
//	String name = "fruit";
}

class Apple extends Fruit
{
	String name = "apple";
}
           

執行結果:

D:\src>java InheritenceTest

apple

【說明】:父類沒有的屬性,之類可以自己添加屬性。

6.關于繼承的3點:

a) 父類有的,子類也有

b) 父類沒有的,子類可以增加

c) 父類有的,子類可以改變

7.關于繼承的注意事項

a) 構造方法不能被繼承

b) 方法和屬性可以被繼承

c) 子類的構造方法隐式地調用父類的不帶參數的構造方法

d) 當父類沒有不帶參數的構造方法時,子類需要使用super來顯式地調用父類的構造方法,super指的是對父類的引用

e) super關鍵字必須是構造方法中的第一行語句。