动手动脑,11.9
2017-11-09 19:24 Robortxin 阅读(151) 评论(0) 编辑 收藏 举报- 为什么子类的构造方法在运行之前,必须调用父类的构造方法?能不能反过来?为什么不能反过来?
构造函数的功能主要用于在类的对象创建时定义初始化的状态。构造一个对象,先调用其构造方法,来初始化其成员函数和成员变量。
子类拥有父的成员变量和成员方法,如果不调用,则从父类继承而来的成员变量和成员方法得不到正确的初始化。
不能反过来调用也是这个原因,因为父类根本不知道子类有什么变量,子类也得不到初始化的父类变量.所以程序不能运行。
2.不可变的“类”有何用?
可以方便和安全地用于多线程环境中,访问它们可以不用加锁,因而能提供较高的性能。
知识点:(子类与父类方法间的关系 扩充(Extends):子类定义的方法父类没有同名
覆盖/重写(Override):子类父类定义了完全一样的方法
重载(Overloads):子类有父类的同名方法,但两者的参数类型或参数数目不一样)
3.
public class ExplorationJDKSource {
/**
* @param args
*/
public static void main(String[] args) {
System.out.println(new A());
}
}
class A{}
public void println(Object x),这一方法内部调用了String类的valueOf方法。
valueOf方法内部又调用Object.toString方法:
public String toString() {
return getClass().getName() +"@" +
Integer.toHexString(hashCode());
}
- 我们来看一段代码:
- 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()方法。
4.在子类中,若要调用父类中被覆盖的方法,可以使用super关键字:
class Father
{
public void display()
{
System.out.println("Father");
}
}
class Son extends Father
{
public void display()
{
super.display();
System.out.println("Son");
}
}
public class Teost {
public static void main(String []args)
{
Son c=new Son();
c.display();
}
}
- 怎样判断对象是否可以转换?
例: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));
}
}
6.现在有三个类:
class Mammal{}
class Dog extends Mammal {}
class Cat extends Mammal{}
针对每个类定义三个变量并进行初始化
Mammal m=null ;
Dog d=new Dog();
Cat c=new Cat();
下列语句哪一个将引起编译错误?为什么?哪一个会引起运行时错误?为什么?
m=d;
d=m;
d=(Dog)m;
d=c;
c=(Cat)m;
d=m 编译错误,基类转换成子类需要强制转换,d=c,错误,两个对象不能互换。
7.请看以下“变态”的类,下述代码的特点是:
子类和父类定义了一模一样的字段和方法
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();
}
}
class Parent{
public int myValue=100;
public void printValue() {
System.out.println("Parent.printValue(),myValue="+myValue);
}
}
class Child extends Parent{
public int myValue=200;
public void printValue() {
System.out.println("Child.printValue(),myValue="+myValue);
}
}
程序运行结果是什么?
Parent.printValue(),myValue=100
Child.printValue(),myValue=200
Child.printValue(),myValue=200
Child.printValue(),myValue=200
Child.printValue(),myValue=201
你如何解释会得到这样的输出?
当子类与父类拥有一样的方法,并且让一个父类变量引用一个子类对象时,到底调用哪个方法,由对象自己的“真实”类型所决定,这就是说:对象是子类型的,它就调用子类型的方法,是父类型的,它就调用父类型的方法。
这个特性实际上就是面向对象“多态”特性的具体表现。
当子类与父类有相同的字段,则子类中的字段会代替或隐藏父类的字段,子类方法中访问的是子类中的字段(而不是父类中的字段)。如果子类方法确实想访问父类中被隐藏的同名字段,可以用super关键字来访问它。
如果子类被当作父类使用,则通过子类访问的字段是父类的。