继承与接口的使用

1.动手实验:继承条件下的构造方法调用。

运行 TestInherits.java 示例,观察输出,注意总结父类与子类之间构造方法的调用关系修改Parent构造方法的代码,显式调用GrandParent的另一个构造函数,注意这句调用代码是否是第一句,影响重大!

结论:

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

在继承时候,构造方法先调用上面的,再进行下面的。

    package yanzheng;

 

class Grandparent {

    public Grandparent() {

        System.out.println("GrandParent Created.");

    }

    public Grandparent(String string) {

        System.out.println("GrandParent Created.String:" + string);

    }

}

 

class Parent extends Grandparent {

    public Parent() {

        //super("Hello.Grandparent.");

        System.out.println("Parent Created");

        //super("Hello.Grandparent.");

    }

}

 

class Child extends Parent {

    public Child() {

        System.out.println("Child Created");

    }

}

 

public class TestInherits {

    public static void main(String args[]) {

        Child c = new Child();

    }

}

 

 

package yanzheng;

 

class Grandparent {

    public Grandparent() {

        System.out.println("GrandParent Created.");

    }

    public Grandparent(String string) {

        System.out.println("GrandParent Created.String:" + string);

    }

}

 

class Parent extends Grandparent {

    public Parent() {

        super("Hello.Grandparent.");

        System.out.println("Parent Created");

        //super("Hello.Grandparent.");

    }

}

 

class Child extends Parent {

    public Child() {

        System.out.println("Child Created");

    }

}

 

public class TestInherits {

    public static void main(String args[]) {

        Child c = new Child();

    }

}

 

 

2.不允许继承的类

final class 类名{

}

(1).以final声明的方法不允许覆盖。

(2).以final声明的变量不允许更改。

(3).利用final,我们可以设计出一种特殊的“只读” 的“不可变类”。

何为“不可变的类”?

创建“不可变的类”的对象后,此对象的属性不可改,而且也无法从此类派生出新子类。String就是一个典型的例子。

不可变的“类”有何用?

&可以方便和安全地用于多线程环境中,

&访问它们可以不用加锁,因而能提供较高的性能。

不可变类的实例:Address.java

JDK中的实例:String

package yanzheng;

//不允许继承的类  2015.11.10

public final class Address

{

private final String detail;

private final String postCode;

 

//在构造方法里初始化两个实例属性

public Address()

{

this.detail = "";

this.postCode = "";

}

public Address(String detail , String postCode)

{

this.detail = detail;

this.postCode = postCode;

}

//仅为两个实例属性提供getter方法

public String getDetail()

{

 return this.detail;

}

 

public String getPostCode()

{

 return this.postCode;

}

//重写equals方法,判断两个对象是否相等。

public boolean equals(Object obj)

{

if (obj instanceof Address)

{

Address ad = (Address)obj;

if (this.getDetail().equals(ad.getDetail()) && this.getPostCode().equals(ad.getPostCode()))

{

return true;

}

}

return false;

}

public int hashCode()

{

return detail.hashCode() + postCode.hashCode();

}

}

 

    3.参看ExplorationJDKSource.java示例

此示例中定义了一个类A,它没有任何成员:

class A { }

示例直接输出这个类所创建的对象

public static void main(String[] args)    {

System.out.println(new A());

}

我们得到了一个奇特的运行结果:

A@1c5f743

后面这一串奇怪的字符其实是hash值。

 

前面示例中,main方法实际上调用的是:

public void println(Object x),这一方法内部调用了String类的valueOf方法。

valueOf方法内部又调用Object.toString方法:

public String toString() {

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

Integer.toHexString(hashCode());

}

hashCode方法是本地方法,由JVM设计者实现:

public  native int hashCode();

 

 

4.神奇的“+”号。

我们来看一段代码(示例Fruit.java ):注意最后一句,一个字串和一个对象“相加”,前页的示例中,Fruit类覆盖了Object类的toString方法。

结论:

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

 

 

5.接口知识。

面向对象语言为什么要引入“接口”?

Java不支持多继承,还可以实现多种功能。

Java中“接口”的语法特性。

定义一个接口,采用关键字interface,实现一个接口,采用关键字implements

接口的成员函数自动成为public的,数据成员自动成为 static和final的。

如果接口不声明为public的,则自动变为package。

一个类可以同时实现多个接口。

可以通过继承接口来扩充已有接口,并形成一个新的接口。

interface OneInterface {

void f1();

}

interface TwoInterface extends OneInterface {

void f2();

}

实现子接口的类,必须实现“父”“子”接口所定义的所有方法,才能被实例化(即new出一个对象)。

接口与抽象类的区别?

抽象类是一个不完全的类,而接口只是表明类应该具有哪些“外部”特征,不涉及任何实现细节。

接口基本上不具备继承的任何具体特点,它仅仅承诺了外界能够调用的方法。

一个类一次可以实现若干个接口,但一个类只能继承一个父类。

posted @ 2015-11-10 11:40  底云飞  阅读(792)  评论(0编辑  收藏  举报