天天看点

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关键字必须是构造方法中的第一行语句。