继承

来源:互联网 发布:河海大学人工智能 编辑:程序博客网 时间:2024/05/14 13:39

概念

继承是面向对象编程的三大特征之一,也是实现代码复用的重要手段。Java中继承具有单继承的特点,每一个类只可以直接继承一个父类,即直接父类,不可以同时继承多个类。但是继承是可以多层继承的,即:父类还有父类,顶级的父类为Object类。也就是说,任何类都是Object的子类,Object是任何类的父类。

 

如果编写的类没有直接继承其他类,默认继承的是Object类

子类 了父类的一些特征。子辈从父辈那里可以继承一笔财富称为继承,子类从父类那里可以继承一些代码称为继承。

继承是如何实现代码的复用?

以已有的类作为父类(基类),从这个父类已有的功能和属性上,在新的类(子类)中,添加其他方法和属性,达到复用代码的目的,而不用再编写父类已存在的代码,这样就达到了代码的复用!

提示:

当我们描述一类事物时候,发现这些事物具备相同的属性,我们将这些共性属性进行抽取,用单独的类来描述共同的属性,让这类事物继承抽取出来的类描述的对象,实现的代码的复用。但是请注意,继承是一类事物共性的向上抽取,所以不能单纯的为了简写代码而使用继承。

JavaJDK中提供了大量的类,这些类通过一层一层的继承,形成一个庞大的继承树,最顶级为Object类,一定要注意,这个继承树的形成是N多个类的共性的抽取,一层一层抽取共性,直至抽取到Object类,而不是说:所有功能的类都是通过Object派生出去的!

//描述猫的时候,继承狗,虽然也具备了name属性,但是意义完全错误。

class Cat extends Dog

{

    String id;

}

如果在描述对象时,只是为了简写代码,不可以使用继承的特性定义了一些和描述对象完全不相关的成员。

如果只是为了简写代码的编写,完全可以将这些不相关的代码编写一个单独的工具类来实现。

[java] view plain copy
  1.  class Dog {  
  2.     Stringname;  
  3.     Stringage;  
  4.     voidmethod1(){  
  5.         System.out.println("今天星期一");  
  6.     }  
  7.     voidmethod2(){  
  8.         System.out.println("天气晴");  
  9.     }  
  10.     voidmethod3(){  
  11.         System.out.println("今天没雾霾");  
  12.     }  
  13. }    
  14. class DaoMang extends Dog  
  15. {  
  16.     /*在这里编写代码时候,需要用到父类的方法,可以 
  17.     直接调用,编写代码确实很爽,但是这和继承思想 
  18.     完全没有任何关系!因为执行父类的那些方法和描述 
  19.     对象没有任何关系!!*/  
  20.     voidmethod(){  
  21.             method1();  
  22.     }  
  23.      
  24. }  
  25. 编写dog继承类代码。  
  26. class Dog {  
  27.     Stringname;  
  28.     Stringage;  
  29.     voidworking(){  
  30.         System.out.println("看家!");  
  31.     }  
  32. }    
  33. class DaoMang extends Dog  
  34. {  
  35.     String id;  
  36. }  


特点:

java继承通过使用extends关键字来实现,实现继承的类被称为子类,被继承类称为父类。例如:动物是狗的父类,狗是哈士奇的父类。

定义格式:

修饰符 class 子类 extends 父类{

 

}

重写:Override:

子类继承父类后,在原有的基础上可以进行扩展,如新增属性、方法,但是有一种情况,例如:狗类具有工作方法搜救犬的工作是搜救,导盲犬的功能是导盲,那这个时候他们的工作方法内容就不一样了,我们需要将他们的工作方法进行单独的修改,那么这个修改的动作就是重写。

定义:子类继承父类后,如果子类的方法与父类的方法名称、参数个数及返回值类型完全一致时,就称为子类中的这个方法重写了父类中的方法。同理,如果子类中重复定义了父类中的已有的属性,则称此子类中的属性重写了父类中的属性。

子类重写了父类的方法或属性,那么该方法或属性便属于子类,而不属于父类,如果还想调用父类中的被重写的方法或属性,使用super.方法名/参数名的方式调用即可。

 

 

[java] view plain copy
  1. class Test  
  2. {  
  3.     publicstatic void main(String[] args){  
  4.         DaoMangdm = new DaoMang();  
  5.         dm.working();  
  6.         Soujiusj = new Soujiu();  
  7.         sj.working();  
  8.     }  
  9. }  
  10.    
  11.    
  12. class Dog {  
  13.     Stringname;  
  14.     Stringage;  
  15.     void working(){  
  16.         System.out.println("看家!");  
  17.     }  
  18. }    
  19. class DaoMang extends Dog  
  20. {  
  21.     String id;  
  22.     voidqita(){  
  23.      
  24.     }  
  25.     voidworking(){  
  26.         System.out.println("引路!");  
  27.     }  
  28. }  
  29. class Soujiu extends Dog  
  30. {  
  31.     String id;  
  32.     voidworking(){  
  33.         System.out.println("搜救!");  
  34.     }  
  35. }  

spuer关键字

定义: super代表当前对象的父类对象。

当创建子类对象,最先拥有的应该是它的父类对象,那么可以使用super关键字代表父类对象,达到访问父类成员的目的!


父类对象都没有怎么可能创建子类对象?

子类覆盖了父类的方法后,子类对象无法直接调用被覆盖的父类中的方法,那么可以使用super关键字来实现调用父类的方法,或者也可以使用类名.方法名调用,但前提这个方法是静态方法(类方法)。

通过super找到该对象的父类对象:

[java] view plain copy
  1. voidworking(){  
  2.     super.working();  
  3.     System.out.println("引路!");  
  4. }  


通过Dao.静态方法执行代码:

[java] view plain copy
  1. static void working(){  
  2.    Dog.working();  
  3.    System.out.println("引路!");  


之前的this关键字是代表当前对象本身。这个时候super代表的是父类对象本身。

同样,super和this不能出现在static关键字修饰的方法中。

因为:static修饰的是静态的,super、this关键字描述的是对象,静态成员是优先于对象存在的。用存在的东西访问不存在的东西是错误的。

 

 


验证:子类调用到父类的属性,该属性属于父类而不属于子类。

1、  在父类中定义name属性,子类没有定义name属性。


2、  在测试时候,调用子类的name属性。



3确定这个子类修改了的name属性其实是属于父类的!


证明:

1、  父类对象被子类引用。

2、  子类继承父类的属性,只是引用指向了父类,并没有将父类的属性进行单独的复制一份作为子类对象本身的属性。


导盲犬与搜救犬的父类对象是同一个吗?

每次创建子类对象,都会单独创建一个该子类的父类对象!他们的父类对象不是同一个,但是他们的父类是同一个!


调用父类构造器:

[java] view plain copy
  1. class Dog {  
  2.     publicDog(String message){  
  3.         System.out.println(message);  
  4.     }  
  5.         Stringname;  
  6. }    
  7. class DaoMang extends Dog  
  8. {  
  9.      
  10.     publicDaoMang(){  
  11.         super("abc");  
  12.     }  
  13.     String id;  
  14.      static void working(){  
  15.         System.out.println("引路!");  
  16.     }  
  17. }  


创建一个子类对象,发生了什么未知的事情?

[java] view plain copy
  1. class Test  
  2. {  
  3.     publicstatic void main(String[] args){  
  4.         /* 
  5.         创建子类对象发生了: 
  6.         1、先执行父类静态代码块 
  7.         2、执行子类静态代码块 
  8.         3、执行父类的构造代码块 
  9.         4、执行父类的构造方法 
  10.         5、执行子类的构造代码块 
  11.         6、执行子类的构造方法 
  12.     */  
  13.         DaoMangdm = new DaoMang();  
  14.     }  
  15. }  
  16. class Dog {  
  17.     static{  
  18.         System.out.println("Dog类的静态代码块执行了!");  
  19.     }  
  20.     {  
  21.         System.out.println("创建Dog对象时构造代码块");  
  22.     }  
  23.    
  24.     publicDog(){  
  25.         System.out.println("Dog的构造器执行了!");  
  26.     }  
  27. }    
  28. class DaoMang extends Dog  
  29. {  
  30.     static{  
  31.         System.out.println("DaoMang类的静态代码块执行了!");  
  32.     }  
  33.     {  
  34.         System.out.println("创建DaoMang对象时构造代码块");  
  35.     }  
  36.     publicDaoMang(){  
  37.         System.out.println(id  + "DaoMang的构造器执行了!");  
  38.     }  
  39. }  
  40.    


 

设置父类与子类同名的成员属性

 

[java] view plain copy
  1. class Test  
  2. {  
  3.     publicstatic void main(String[] args){  
  4.         DaoMangdm = new DaoMang();  
  5.         dm.setName("金毛");  
  6.         dm.setSuperName("SuperName");  
  7.         Stringname = dm.getName();  
  8.         StringsuperName = dm.getSuperName();  
  9.         System.out.println("子类对象的name:" + name +"\n 父类对象的name是:" + superName);  
  10.     }  
  11. }  
  12. class Dog {  
  13.     Stringname;  
  14. }    
  15. class DaoMang extends Dog  
  16. {  
  17.     Stringname;  
  18.     publicvoid setName(String name){  
  19.         this.name= name;  
  20.     }  
  21.     publicvoid setSuperName(String name){  
  22.         super.name= name;  
  23.     }  
  24.     publicString getName(){  
  25.         returnname;  
  26.     }  
  27.     publicString getSuperName(){  
  28.         returnsuper.name;  
  29.     }  
  30. }  
0 0
原创粉丝点击