动手动脑4

 

1.TestInherits.java

public class TestInherits 
{
    public static void main(String args[])
	 {

        	Child c = new Child();
  }

}

  输出结果:

修改代码:

  输出结果:

结论:通过 super 调用基类构造方法,必须是子类构造方法中的第一个语句。

 

2. 为什么子类的构造方法在运行之前,必须调用父类的构造方法?能不能反过来?为什么不能反过来?

构造方法用于对基类的初始化。当构造一个对象时,先调用构造函数对成员函数和成员变量进行初始化,。子类继承了父类的成员函数和成员变量,若不进行调用,则不会对父类的初始化。

3.ExplorationJDKSource.java

public class ExplorationJDKSource {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		System.out.println(new A());
	}

}

class A{}

  

在编译源码时,当遇到没有父类的类时,编译器会定义的默认的父类(一般为Object),public void println(Object x),这一方法内部调用了String类的valueOf方法。valueOf方法内部又调用Object.toString方法:

public String toString() {

return getClass().getName() +"@" +

Integer.toHexString(hashCode());

}

 

4.

public class Fruit
{
		
	public String toString()
	{
		return "Fruit toString.";
	}

	public static void main(String args[])
	{
		Fruit f=new Fruit();
		System.out.println("f="+f);
	//  System.out.println("f="+f.toString());
	}
}

  输出结果:

 

 

结论:在+”运算中,当任何一个对象与一个String对象,连接时,会隐式地调用其toString()方法,默认情况下,此方法返回“类名 @ + hashCode”。为了返回有意义的信息,子类可以重写toString()方法。

5. 方法覆盖

 

public class parents {
public void parents(){
	System.out.println("parent!");
}
public void parent1(){
	System.out.println("parent1!");
}
}
public class child extends parents {
public void child(){
        super.parents();
}
public void parents(){
	System.out.println("child");
}
public static void main(String[]args){
	child ch=new child();
	ch.parents();
	ch.child();
	ch.parent1();
}
}

 

  输出结果:

 

6. TestInstanceof.Java

public class TestInstanceof
{
	public static void main(String[] args) 
	{
		//声明hello时使用Object类,则hello的编译类型是Object,Object是所有类的父类
		//但hello变量的实际类型是String
		Object hello = "Hello";
		//String是Object类的子类,所以返回true。
		System.out.println("字符串是否是Object类的实例:" + (hello instanceof Object));
		//返回true。
		System.out.println("字符串是否是String类的实例:" + (hello instanceof String));
		//返回false。
		System.out.println("字符串是否是Math类的实例:" + (hello instanceof Math));
		//String实现了Comparable接口,所以返回true。
		System.out.println("字符串是否是Comparable接口的实例:" + (hello instanceof Comparable));
		String a = "Hello";
		//String类既不是Math类,也不是Math类的父类,所以下面代码编译无法通过
		//System.out.println("字符串是否是Math类的实例:" + (a instanceof Math));
	}
}

  

 

输出结果:

7. 类型转换

 

 

class Mammal{}
class Dog extends Mammal {}
class Cat extends Mammal{}

public class TestCast
{
	public static void main(String args[])
	{
		Mammal m;
		Dog d=new Dog();
		Cat c=new Cat();
		m=d;
		//d=m;
		d=(Dog)m;
		//d=c;
		//c=(Cat)m;

	}
}

  

结果:d=m;  d=c;有错误,c=(Cat)m正确

结论:在继承中,子类可以自动转换成父类,但父类转换成子类只有引用类型真正身份才会转换成功,否则会失败。

 8.

public class ParentChildTest {
	public static void main(String[] args) {
		Parent parent=new Parent();
		parent.printValue();
		Child child=new Child();
		child.printValue();
		
		parent=child;
		parent.printValue();
		
		parent.myValue++;
		parent.printValue();
		
		((Child)parent).myValue++;
		parent.printValue();
		
	}
}

 

 

 

 

 

结论:由此可得Java的一些语法特性(多态):

当子类与父类拥有一样的方法,并且让一个父类变量引用一个子类对象时,到底调用哪个方法,由对象自己的“真实”类型所决定,这就是说:对象是子类型的,它就调用子类型的方法,是父类型的,它就调用父类型的方法。

如果子类与父类有相同的字段,则子类中的字段会代替或隐藏父类的字段,子类方法中访问的是子类中的字段(而不是父类中的字段)。如果子类方法确实想访问父类中被隐藏的同名字段,可以用super关键字来访问它。 如果子类被当作父类使用,则通过子类访问的字段是父类的。

因此,我们进行程序设计时应避免子类与父类同名的字段!

9.

public class TestPolymorphism
{


    public static void main(String args[])
    {

        Parent p=new Parent();

        p.Introduce();

        System.out.println(p.value);

        p=new Son();

        p.Introduce();

        System.out.println(p.value);

        p=new Daughter();

        p.Introduce();

        System.out.println(p.value);


    }

  

多态代码:当多个类实现同一接口(或派生自同一抽象类)时,针对这些类所创建的对象调用接口所定义的方法时,会分别调用相应的类的具体实现代码。

posted @ 2018-11-04 14:29  竹林清竹  阅读(115)  评论(0编辑  收藏  举报