java继承知识点整理

上一篇 / 下一篇  2013-04-24 09:56:13 / 个人分类:java编程

java中方法的继承,覆盖

转载



这些天在学习java,学到继承的时候,感觉头脑已经一片混乱了,在网上搜索了下,发现这篇日志正好可以解了自己心中的疑惑,觉得作者总结得特别好,如下:
首先要明确一点,子类在继承父类时,构造函数是不能被继承的。当创建子类的实例时,子类的构造函数要调用父类的构造函数,也就是说父类要先于子类构造。
子类的构造函数可以通过super关键字显式调用父类中的构造函数。如果子类中的构造函数没有显式调用父类中的构造函数,编译器就会自动在子类的构造函数中调用父类中参数为空的构造函数。当父类中没有定义任何构造函数时,编译器就会为它指定一个参数为空的默认的构造函数;如果父类中定义了构造函数,那么编译器就不会为它指定一个参数为空的默认构造函数了。因此,如果某个类有可能成为其他类的父类,为了避免发生不必要的编译错误,最好为它编写一个参数为空的构造函数。

父类Sup中没有定义构造函数,编译程序将为它指定一个参数为空的默认构造函数。子类Sub中也没有定义构造函数,编译程序也会为它指定一个参数为空的默认的构造函数,并且会在这个默认的构造函数中调用父类的参数为空的构造函数

public class Sub extends Sup{
   //
子类中没有定义构造函数
   public static void main(String args[]){
       Sub sub=new Sub();
   }
}

class Sup{
   //
父类中没有定义构造函数
}

父类Sup中没有定义构造函数,编译程序将为它指定一个参数为空的默认构造函数。子类定义了一个带整型参数的构造函数,在这个构造函数中子类没有显式调用父类的构造函数,所以编译器为在它里面调用父类中参数为空的构造函数

public class Sub extends Sup{
   //
子类中定义类一个带整型变量参数的构造函数
   public Sub(int i){
       //
   }
   public static void main(String args[]){
       Sub sub=new Sub(1);
   }
}
class Sup{
   //
父类中没有定义构造函数
}

父类中定义了一个带整型参数的构造函数,因此编译器不再为它指定参数为空的默认的构造函数。子类中也定义了一个带整型参数的构造函数。编译时,编译器将试图在子类的构造函数中调用父类的参数为空的构造函数,但是父类中没有定义参数为空的构造函数,所以编译程序将会报错。排错的方法时在子类的构造函数中显示调用父类的构造函数,或者在父类中添加一个带空参数的构造函数。

public class Sub extends Sup{
   //
子类中定义类一个带整型变量参数的构造函数
   public Sub(int i){
       //
   }
   public static void main(String args[]){
       Sub sub=new Sub(1);
   }
}

class Sup{
   //
父类中定义了一个带整型参数的构造函数
   public Sup(int i){
       //
   }
}

public class Sub extends Sup{
   //
子类中定义类一个带整型变量参数的构造函数
   public Sub(int i){
       super(i);//
调用父类中的构造函数
   }
   public static void main(String args[]){
       Sub sub=new Sub(1);
   }
}

class Sup{
   //
父类中定义了一个带整型参数的构造函数
   public Sup(int i){
       //
   }
}

排错方法2

public class Sub extends Sup{
   //
子类中定义类一个带整型变量参数的构造函数
   public Sub(int i){
       //
   }
   public static void main(String args[]){
       Sub sub=new Sub(1);
   }
}

class Sup{
   //
父类中定义了一个带整型参数的构造函数
   public Sup(int i){
       //
   }
   //
定义一个带空参数的构造函数
   public Sup(){
       //
   }

}

类方法和实例方法在继承过程中的问题:

overiding重写 父子类相同方法名,返回值,参数类型

  如果子类的实例方法和父类的实例方法具有相同的标记,子类的方法将覆盖父类的方法。但是如果子类的方法和父类的方法具有相同的标记,但是具有不同的返回值类型,编译程序将会报错。排错的方法是修改子类中这个方法的返回值类型,使它父类中相同标记的方法的返回值一样。

public class Sub extends Sup{
   //
子类中的这个方法父类中的方法有相同的标记,
   //
但返回值不同,编译程序就会报错
   int test(){
       return 1;
   }
}

class Sup{
   void test(){
       //
   }
}
  
排错:

public class Sub extends Sup{
   //
子类中的方法正确覆盖了父类中的方法
   void test(){
       //
   }
}

class Sup{
   void test(){
       //
   }
}

同样如果子类的类方法和父类的类方法具有相同的标记,那么子类的类方法将隐藏父类的类方法。注意这里不叫覆盖,而叫隐藏,两者的区别将在后面讨论。同样,如果子类的类方法和父类的类方法具有相同的标记和不同的返回值,编译程序也会报错。解决的问题的方法同实例方法一样。

实例方法不能覆盖类方法(编译时报错)
public class Sub extends Sup{
   //
实例方法不能覆盖类方法,编译时报错
   void test(){
       //
   }
}

class Sup{
   static void test(){
       //
   }
}
  
类方法不能隐藏实例方法(编译时报错)public class Sub extends Sup{
   //
类方法不能隐藏实例方法,编译时报错
   static void test(){
       //
   }
}

class Sup{
    void test(){
       //
   }
}

覆盖和隐藏的区别。对于隐藏的方法,运行时系统调用当前对象引用的编译时类型中定义的方法;对于覆盖的方法,运行时系统调用当前对象引用运行时类型中定义的方法。一个是调用编译时类型中定义的方法,一个是调用运行时类型中定义的方法。通过下面这个例子可以直观的看出两者之间的差别。

class Planet {
   public static void hide() {
       System.out.println("The hide method in Planet.");
   }

   public void override() {
       System.out.println("The override method in Planet.");
   }
}

class Earth extends Planet {
   public static void hide() {
       System.out.println("The hide method in Earth.");
   }

   public void override() {
       System.out.println("The override method in Earth.");
   }

   public static void main(String args[]) {
       Earth earth = new Earth();
       Planetplanet = (Planet) earth;
       planet.hide(); // result:"The hide method in Planet."
       planet.override(); // result:"The override method in Earth."
   }
}

 

  (1)子类方法的名称、参数签名和返回类型必须与父类方法的名称、参数签名和

返回类型一致。例如以下代码将导致编译错误。

public class Base{

      public void method(){…}

}

public class Sub extends Base{

      public int method(){//编译错误,返回类型不一致

             return 0;

}

}

   Java编译器首先判断Sub类的method()方法与Base类的method()方法的参数名,由于两者一致,因此Java编译器认为Sub类的method()方法试图覆盖父类的方法,既然如此,Sub类的method()方法就必须和被覆盖的方法具有相同的返同类型。

以下代码中子类覆盖了父类的一个方法,然后又定义了一个重载方法,这是合法的。

public class Base{

      public void method(){…}

}

public class Sub entends Base{

      public void method(){…}  //覆盖Base类的method()方法

      public int method(int a){      //重载method()方法

             return 0;

      }

}

(2)子类方法不能缩小父类方法的访问权限。例如以下代码中子类的method()方法是私有的,父类的method()方法是公共的,子类缩小了父类方法的防问权限,这是无效的方法覆盖,将导致编译错误。但可以放大。

public class Base{

      public void method(){…}

}

public class Sub extends Base{

      private void method(){…}//编译错误,子类方法缩小了父类方法的访问权限

}

public class Base{

      void method(){…}

}

public class Sub extends Base{

      public void method(){…}//这是可以的。

}

3)子类方法不能抛出比父类方法更多的异常。子类方法抛出的异常必须和父类方法抛出的异常相同,或者子类方法抛出的异常是父类方法抛出的异常类的子类。

4)方法覆盖只存在于子类和父类(包括直接父类和间接父类)之间。在同一个类中方法只能被重载,不能被覆盖

5)父类的静态方法不能被子类覆盖为非静态方法。

6)子类可以定义与父类的静态方法同名的静态方法,以便在子类中隐藏父类的静态方法。在编译时,子类定义的静态方法也必须满足与方法覆盖类似的约束:方法的参数名一致,返回类型一致,不能缩小父类方法的访问权限,不能抛出更多的异常。

(7)父类的非静态方法不能被子类覆盖为静态方法。

8)父类的私有方法不能被子类覆盖。

9)父类的抽象方法可以被子类通过两种途径覆盖:一是子类实现父类的抽象方法;二是子类重新声明父类的抽象方法。

 

(10)父类的非抽象方法方法可被覆盖为抽象方法。

 


TAG: java继承

 

评分:0

我来说两句

我的栏目

日历

« 2024-05-09  
   1234
567891011
12131415161718
19202122232425
262728293031 

数据统计

  • 访问量: 1042
  • 建立时间: 2013-04-24
  • 更新时间: 2013-09-12

RSS订阅

Open Toolbar