类的扩展

       描述如何扩展( extend)子类化( subclassed)一个类,描述如何将扩展类的实例用于任何要求使用原类的地方,描述这种能力的术语称作多态( polymorphism),其含义是指一个给定的类可以具有多种形态,既可以作为它本身的类,又可以作为任何它所扩展的类

       通过扩展得到的新类称作被扩展的类的子类( subclass)或者扩展类( extended class),而被扩展的类则称作超类( superclass)。类的扩展提供了两种形式的继承:

1)契约(类型)的继承:通过这种继承,子类可以获得超类的类型,因此它可以多态地用于所有使用超类的地方。

2)实现的继承:通过这种继承,子类可以获得超类中可访问到的字段和方法的实现。

       在使用类扩展机制时,契约的继承和实现的继承总是同时出现。但是可以通过使用接口来定义新的独立于实现的类型,也可以通过人为地使用组合( composition)转发( forwarding)来重用现有的实现,后面的这种做法并不会对类型造成影响。

一个简单的扩展类例子:

超类(父类)Father

package test;

public class Father {
	public String name = "father";
	public String message = "father's message";

	public Father() {

	}

	public Father(String name) {
		this.name = name;
	}

	public void outMessage() {
		System.out.println("this is father");
	}
}

扩展类(子类)Child

package test;

public class Child extends Father {
	public String name = "child";

	public Child() {
		super();
	}

	public Child(String name) {
		super("father");
		this.name = name;
	}

	@Override
	public void outMessage() {
		System.out.println("this is child");
	}
}

测试类Test

package test;

public class Test {
	public static void main(String[] args) {
		Father f = new Child();
		System.out.println(f.name);
		f.outMessage();
		Child c = new Child();
		System.out.println(c.name);
		c.outMessage();
		System.out.println(c.message);
	}
}

       注意,扩展类(子类)的构造器的构造方法都会自动调用超类(父类)的无引元构造器,也就是说,扩展类构造器的第一条语句被认为是如下这条语句:

super();

       如果超类没有无引元的构造器,就必须显式地调用另一个构造器

       当一个方法访问某个已经被子类重定义过的对象成员时,这个方法将会引用的成员取决于成员的类型、可访问性以及引用它的方式。看一个简单的例子:

package test;

public class Father {
	public String name = "father";
	
	public String getName(){
		return name;
	}
}

package test;

public class Child extends Father {
	public String name = "child";

	public String getName(){
		return name;
	}
}

package test;

public class Test {
	public static void main(String[] args) {
		Child c = new Child();
		Father f = c;
		
		System.out.println("child.getName:"+c.getName());
		System.out.println("father.getName:"+f.getName());
		System.out.println("child.name:"+c.name);
		System.out.println("father.name:"+f.name);
	}
}

       对于getName方法,具体应调用getName方法的哪个版本是由对象的实际类而不是引用的类型决定的。而对于name字段,具体应访问哪个类的字段是由引用的类型决定的,不是由对象的实际类决定的。这也是为什么要将一些类定义为包含只能通过方法访问的私有数据的理由。在类的所有非静态方法中都可以使用super关键字,在字段访问和方法调用中,super起到了一个引用的作用,它将当前对象引用为其超类的一个实例。只有在使用super的情况下,方法实现的选择权才是由引用类型来掌控。

package test;

public class Child extends Father {
	public String name = "child";

	public String getName(){
		return name;
	}
	
	public void printName(){
		System.out.println("child.getName:"+this.getName());
		System.out.println("father.getName:"+super.getName());
		System.out.println("child.name:"+this.name);
		System.out.println("father.name:"+super.name);
	}
	
	public static void main(String...args){
		Child c = new Child();
		c.printName();
	}
}


你可能感兴趣的:(类的扩展)