java中的继承详解 extends会产生那些事

   继承:
 判断继承的标准 “IS-a”
 在子类中可以增加域、增加方法,然而绝对不能够删除继承的任何域和方法;
 如果子类的构造器没有显式的调用超类的构造器,则将自动地调用超类默认(没有参数的)构造器,如果超类没有不带参数的构造器,并且在子类的构造器中又没显式声明地调用超类的其他构造器,则Java编译器将报告错误。从这句话中可以得出,子类无论如何都会调用超类的构造器。
也就是说:
    子类一定会调用父类的构造:
     当在子类中不写Super(有参)时,会自动调用Super(无参)。
     当写了Super(参数),则找父类参数匹配的构造。
     如果父类没有不带参数的构造,子类的构造中又没有显式的声明调用父类的其他构造,则不能通过编译
class TestSuper{    
  TestSuper(int i){} 
} 
class TestSub extends TestSuper{ 
 
} 
public class TestAll{    
  public static void main(String args[]){    
  new TestSub();      
  } 
} 

不能编译成功

解决方法1:在子类TestSub中添加下面的构造:
public TestSub() {
  super(0);
  }
解决方法2:在TestSuper类添加无参数构造函数TestSuper(){}
或:在TestSub添加无参数构造函数TestSub (){}

更简单的理解:如果不调用子类内的基础类构造器(TestSuper),编译器就会报告自己找不到TestSuper()形式的一个构造器,除此以外,在子类构造器中,对超类构造器的调用是必须做的第一件事情,
编译器会强迫我们在子类构造器的主体中首先设置对超类构造器的调用,这意味着,在它之前不能出现任何东西。所以我们看到:注意:使用super调用构造器的语句必须是子类构造器的第一条语句


在继承中有两上关键字:this和super
这两个关键字都有两种用法:
This: 引用隐式参数,这种情况下,谁调用,this就代表谁。
    调用该类其它的构造方法;
Super: 调用超类的方法;
    调用超类的构造器;
可以看到,Super与超类有关,是调用超类的方法或构造的。而this只与本类有关。

重写的条件是必须存在继承,并且只有方法具有重写。子类中的普通方法(也即非静态方法)重写只能重写父类的非静态方法。静态方法可以重写,但是要求父子类的方法都必须是静态的方法才行。
可以将其总结如下:
 必须存在继承且只有方法具有重写
 非静态方法只能重写父类的非静态方法
 静态方法可以重写,但要求父子类的方法都必须是静态方法。静态方法重写不支持多态,依然调用父类的方法。


★重写的语法要求:
方法名、参数列表、返回类型必须相同。
访问权限不能更小,也就是说子类重写的方法访问权限不能比父类的小。
不能抛出更大的异常,也就是说不能抛出比父类更大的异常。

继承后程序的运行顺序:
    先父后子;
    先This,后Super;
    先语句块,后构造器;
★什么能被继承:
  属性能被继承,但只有Public的属性能够被调用
  只有Public 的方法能被继承,私有方法不能被继承
  构造不能继承,但一定会被子类调用。

★继承与设计:
  为什么需要继承?继承的好处是什么?
  如果你的多个类中具有相同的属性,就可以把那些相同的属性提取出来做为父类,其他那些类继承父类,子类将会拥有父类的所有的非私有的属性和方法,这样即可以减少代码的冗余,又增强了代码的可读性和健壮性

   “继承”是面向对象软件技术当中的一个概念。如果一个类A继承自另一个类B,就把这个A称为"B的子类",而把B称为"A的父类"。继承可以使得子类具有父类的各种属性和方 法,而不需要再次编写相同的代码。在令子类继承父类的同时,可以重新定义某些属性,并重写某些方法,即覆盖父类的原有属性和方法,使其获得与父类不同的功能。

继承的基本概念
1.继承是面向对象的三大特性之一。(封装,继承,多态)
2.被继承的类是父类,继承父类的类是子类
3.继承可以使一个对象直接使用另以对象的属性和方法
4.继承可实现代码重用


继承的限制
1.java只能显示单继承,即一个类只能有一个父类
2.允许多重继承
3.继承只能继承非私有的属性和方法
4.构造方法不能被继承

来看例子

情况一:

Java代码  收藏代码
public class Mystring {  
      
    public static void main(String[] args) {  
          
          student ok=new student("xiaoming");  
              ok.say();//say方法也被继承过来  
    }  
  
}  
class person  
{  
    public String name;   
    //构造方法  
    public person()  
    {  
       System.out.println("我是person构造方法");  
    }  
    public void say()  
    {  
        System.out.println("名字是 :"+name);  
    }  
}  
class student extends person//继承person类  
{  
    public student(String name)  
    {  
          this.name=name;//person的name属性被继承过来  
    }     
}  

输出结果为:



得出结论1:子类实例化时,首先会调用父类的构造方法,之后自己在进行实例化操作

情况二:



    此时引入关键字super。super表示父类的引用,可以调用父类的方法和属性。如调用父类的say方法,可以用。super.say()调用。

得出结论二:父类无默认构造函数时,子类必须显示的调用父类的构造方法


继承方法的重写

   概念:在java中,子类能继承父类中的方法,但有时子类并不想原封不动的使用父类的方法,而想做一些修改,这就需要采用方法的重写,又称方法覆盖。

方法重写需要注意的特性
1.发生重写的父类和子类的两个方法的返回值,函数名,参数列表必须完全一致
2.子类抛出的异常不能超过父类相应方法抛出的异常
3.子类方法的访问级别不能低于父类相应方法的访问级别(如父类方法时protected,子类重写就要用protected或public)

如:
Java代码  收藏代码
public class Mystring {  
      
    public static void main(String[] args) {  
          
          student ok=new student("xiaoming");  
          ok.say();//say方法也被继承过来  
    }  
  
}  
class person  
{  
    public String name;   
     
    public void say()  
    {  
        System.out.println("名字是 :"+name);  
    }  
}  
class student extends person//继承person类  
{  
    public student(String name)  
    {  
        this.name=name;//person的name属性被继承过来  
    }     
      
    //say方法重写  
    public void say()  
    {  
        System.out.println("重写过得方法       名字是 :"+name);  
      
    }  
}  


输出结果:


猜你喜欢

转载自jzgl-javaeye.iteye.com/blog/2391273