首页 > 代码库 > 接口与继承

接口与继承

1. 继承条件下的构造方法调用

(1)源代码

package demo1;

//一级级的调用,构造时先调用基类的构造函数;

//super

//构造函数调用必须是构造函数中的第一个语句

class Gradeparent

{

   public Gradeparent()//默认构造函数

   {

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

   }

   public Gradeparent(String string)//重载

   {

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

     

   }

}

class Parent extends Gradeparent

{

   public Parent()

   {

      //super(" hello ");

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

     

   }

}

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)设计思想

先定义一个Gradeparent类,再定义一个Parent,直接继承Gradeparent,定义一个Child类,直接继承Parent类,为了看调用顺序,所以在每个构造函数中都有输出语句,用于判别是哪个先输出的,先调用的哪个;如果类中有无参构造函数和有参构造函数,默认的是无参构造函数,要是想调用父类的构造函数,可以用super。

(3)程序结果截图

第一个是没有用super,第二个用到了super,super()括号中有参数,所以就调用了有参数的基类构造方法。

技术分享技术分享

(4)结论

父类与子类之间构造方法的调用关系修改Parent构造方法的代码,显式调用GrandParent的另一个构造函数,注意这句调用代码是否是第一句,影响重大!

通过 super 调用基类构造方法,必须是子类构造方法中的第一个语句。继承基类的方法是加extends关键词。

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

构造函数的作用就是初始化,就像亲属关系中,只有有了父亲,才会有孩子,不能反过来。

3. 何为“不可变的类”?

创建“不可变的类”的对象后,此对象的属性不可改,而且也无法从此类派生出新子类。String就是一个典型的例子。不可变的“类”可以方便和安全地用于多线程环境中,访问它们可以不用加锁,因而能提供较高的性能。

(1)源程序

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();

   }

}

(2)设计思想

定义不允许继承的类,类中有两个参数,一个无参数一个有参数,进行方法的重载,类中有两个实例属性,还有get函数,得到实例属性,equals方法判断对象是否是相等

4.为什么会输出这样的结果

(1)源程序

package demo1;

public class ExplorationJDKSource {

 

   /**

    * @param args

    */

   public static void main(String[] args) {

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

   }

 

}

class A{}

(2)截图技术分享

(3)结果分析

前面示例中,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();

5. 方法覆盖

(1)源代码

//抽象类和接口的设计

//陈晓阳 2016.11.11

public class Shape {

   public static void main(String args[])

   {

      Rectangle a=new Rectangle(3,4);

      System.out.print("面积"+a.getArea());

   }

/*void showArea()//抽象方法,求面积并且显示

{

  

}*/

 

}

 interface DiagArea//定义接口类

{

   double getDiagonal();//求对角线长度方法

   double getArea();//求面积

}

class Rectangle implements DiagArea//矩形类,实现接口

{

   int a,b;//表示长和宽

   Rectangle()

   {

      a=0;b=0;

   }

   Rectangle(int a1,int b1)

   {

      a=a1;b=b1;

   }

   public double getDiagonal()//覆盖,求对角线长

   {

      return Math.sqrt(a*a+b*b);

   }

   public double getArea()//覆盖,求面积

   {

      return a*b;

   }

}

class  Square extends Rectangle//正方形继承矩形类

{

   int x;//正方形的边

   //构造函数,进行初始化

   Square()

   {

      x=0;

   }

   Square(int aa)

   {

      a=aa;

   }

   public double getDiagonal()//求对角线

   {

      return Math.sqrt(a*a*2);

   }

   public double getArea()//求面积

   {

      return a*a;

   }

   void display()//显示边长、面积、对角线长

   {

      System.out.println("正方形的边长、面积、对角线分别是:");

      System.out.println(x+" "+getArea()+" "+getDiagonal());

   }

}

//class  Circle

(2)设计思想

定义一个接口,里面有一些函数,实现接口,在里面实现覆盖,接着在主方法中定义变量,调用覆盖后的结果。

(3)截图技术分享

(4)编译错误,注意事项

覆盖方法的允许访问范围不能小于原方法。覆盖方法所抛出的异常不能比原方法更多。声明为final方法不允许覆盖。例如,Object的getClass()方法不能覆盖。不能覆盖静态方法,覆盖时要用public。

接口与继承