黑马程序员————继承+子父类相关特点

来源:互联网 发布:淘宝客收徒弟 编辑:程序博客网 时间:2024/06/05 16:12

一、      面向对象(继承)

概述:

Java继承是面向对象的最显著的一个特征。继承是从已有的类中派生出新的类,新的类能吸收已有类的数据属性和行为,就无需再定义这些属性和行为,并能扩展新的能力。新类可以称为子类,已有的这个类称为父类或者超类。例如:猫和豹子都是猫科动物,那么就可以说描述猫这个对象创建的类,是子类;而描述猫科动物这个对象创建的类,就是父类。

 

形象理解:

将学生和工人的共性描述提取出来,单独进行描述,

只要让学生和工人与单独描述的这个类有关系,通过继承就可以了。

 

继承特点:

1,提高了代码的复用性。

2,让类与类之间产生了关系。有了这个关系,才有了多态的特性。

 

注意:

千万不要为了获取其他类的功能,简化代码而继承。

必须是类与类之间有所属关系才可以继承。所属关系 is a。(不要想玩人家Iphone就乱认爹的道理)

 

Java语言中:java只支持单继承,不支持多继承。

 

因为多继承容易带来安全隐患:当多个父类中定义了相同功能,

当功能内容不同时,子类对象不确定要运行哪一个。

但是java保留这种机制。并用另一种体现形式来完成表示。多实现(抽象类,实现抽象类)。

 

java支持多层继承。也就是一个继承体系

 

如何使用一个继承体系中的功能呢?

 

想要使用体系,先查阅体系父类的描述,因为父类中定义的是该体系中共性功能。

通过了解共性功能,就可以知道该体系的基本功能。

那么这个体系已经可以基本使用了。

那么在具体调用时,要创建最子类的对象,为什么呢?

一是因为有可能父类不能创建对象,

二是创建子类对象可以使用更多的功能,包括基本的也包括特有的。

 

简单一句话:查阅父类功能,创建子类对象使用功能。

 例如:

[java] view plaincopyprint?
  1. class A  
  2.   
  3. {  
  4.   
  5.          void show()  
  6.   
  7.          {  
  8.   
  9.                    System.out.println("a");  
  10.   
  11.          }  
  12.   
  13. }  
  14.   
  15. class B  
  16.   
  17. {  
  18.   
  19.          void show()  
  20.   
  21.          {  
  22.   
  23.                    System.out.println("b");  
  24.   
  25.          }  
  26.   
  27. }  
  28.   
  29.    
  30.   
  31. class C extends A,B  
  32.   
  33. {}  
  34.   
  35.    
  36.   
  37. C c = new C();  
  38.   
  39. c.show();   


 

二、      子父类出现后,类成员的特点

类中成员:

1,变量。

2,函数。

3,构造函数。

 

1.       子父类中变量的特点

1,变量

如果子类中出现非私有的同名成员变量时,

子类要访问本类中的变量,用this

子类要访问父类中的同名变量,用super。

 

super的使用和this的使用几乎一致。

this代表的是本类对象的引用。

super代表的是父类对象的引用。

 

如果子类和父类有相同名称的变量时,子类继承父类后,在子类中默认使用的是自己的变量,

因为在子类中是this.num省略了this。如果要用父类的变量只需要在变量前加上super

 

当只有子类对象时,this和super指向同一个对象。(多态)

子类不能继承父类的私有属性, 但是父类可以提供被子类访问私有成员变量的方法

 

[java] view plaincopyprint?
  1. class Fu   
  2. {  
  3.     private int num = 4;  
  4.     public void setNum(int num)  
  5.     {  
  6.         this.num =num;  
  7.     }  
  8.     public int getNum()  
  9.     {  
  10.         return this.num;  
  11.     }  
  12. }  
  13.   
  14. class Zi extends Fu  
  15. {  
  16.     //int num = 5;  
  17.     void show()  
  18.     {  
  19.         System.out.println(num);  
  20.     }  
  21. }  
  22.   
  23. class  ExtendsDemo2  
  24. {  
  25.     public static void main(String[] args)   
  26.     {  
  27.         Zi z = new Zi();  
  28.         z.show();  
  29.         //System.out.println(z.num+"...."+z.num);  
  30.     }  
  31. }  


2.       子父类中函数的特点-覆盖(重写)

有利于功能扩展。

程序升级只需覆盖父类,不需修改父类代码(灾难性修改)。

 

2,子父类中的函数。

当子类出现和父类一模一样的函数时,

当子类对象调用该函数,会运行子类函数的内容。

如同父类的函数被覆盖一样。

 

这种情况是函数的另一个特性:重写(覆盖)

 

 

当子类继承父类,沿袭了父类的功能,到子类中,

但是子类虽具备该功能,但是功能的内容却和父类不一致,

这时,没有必要定义新功能,而是使用覆盖特殊,保留父类的功能定义,并重写功能内容。

 

覆盖:

1,子类覆盖父类,必须保证子类权限大于等于父类权限,才可以覆盖,否则编译失败。

2,静态只能覆盖静态。

 

记住大家:

重载:只看同名函数的参数列表。

重写:子父类方法要一模一样。

 例如:

[java] view plaincopyprint?
  1. class Fu  
  2.   
  3. {  
  4.   
  5.          void show()//int show()的话不覆盖,编译错误,类型不同  
  6.   
  7.          {  
  8.   
  9.                    System.out.println("fu show");  
  10.   
  11.          }  
  12.   
  13.          void speak()  
  14.   
  15.          {  
  16.   
  17.                    System.out.println("vb");  
  18.   
  19.          }  
  20.   
  21. }  
  22.   
  23.    
  24.   
  25. class Zi extends Fu  
  26.   
  27. {  
  28.   
  29.          void speak()  
  30.   
  31.          {  
  32.   
  33.                    System.out.println("java");  
  34.   
  35.          }  
  36.   
  37.          void show()  
  38.   
  39.          {  
  40.   
  41.                    System.out.println("zi show");  
  42.   
  43.          }  
  44.   
  45. }  
  46.   
  47.    
  48.   
  49.    
  50.   
  51. class ExtendsDemo3   
  52.   
  53. {  
  54.   
  55.          public static void main(String[] args)   
  56.   
  57.          {  
  58.   
  59.                    Zi z = new Zi();  
  60.   
  61.                    z.speak();  
  62.   
  63.    
  64.   
  65.          }  
  66.   
  67. }  
  68.   
  69.    
  70.   
  71.    
  72.   
  73. class Tel  
  74.   
  75. {  
  76.   
  77.          void show()  
  78.   
  79.          {  
  80.   
  81.                    System.out.println("number");  
  82.   
  83.          }  
  84.   
  85.            
  86.   
  87. }  
  88.   
  89.    
  90.   
  91. class NewTel extends Tel  
  92.   
  93. {  
  94.   
  95.          void show()  
  96.   
  97.          {  
  98.   
  99.                    //System.out.println("number");  
  100.   
  101.                    super.show();  
  102.   
  103.                    System.out.println("name");  
  104.   
  105.                    System.out.println("pic");  
  106.   
  107.          }  
  108.   
  109. }  


 

3.       子父类中构造函数的特点-子类实例化过程

子父类中的构造函数。

 

在对子类对象进行初始化时,父类的构造函数也会运行,

那是因为子类的构造函数默认第一行有一条隐式的语句 super();

super():会访问父类中空参数的构造函数。而且子类中所有的构造函数默认第一行都是super();

 

为什么子类一定要访问父类中的构造函数。

 

因为父类中的数据子类可以直接获取。所以子类对象在建立时,需要先查看父类是如何对这些数据进行初始化的。

所以子类在对象初始化时,要先访问一下父类中的构造函数。

如果要访问父类中指定的构造函数,可以通过手动定义super语句的方式来指定。

 

注意:super语句一定定义在子类构造函数的第一行。(初始化动作要先运行)

 

子类的实例化过程。

 

结论:

子类的所有的构造函数,默认都会访问父类中空参数的构造函数。

因为子类每一个构造函数内的第一行都有一句隐式super();

 

当父类中没有空参数的构造函数时,子类必须手动通过super语句形式来指定要访问父类中的构造函数。

 

当然:子类的构造函数第一行也可以手动指定this语句来访问本类中的构造函数。

子类中至少会有一个构造函数会访问父类中的构造函数。

例如:

[java] view plaincopyprint?
  1. class Fu //extends Object  
  2.   
  3. {  
  4.   
  5.          int num ;  
  6.   
  7.          Fu()  
  8.   
  9.          {  
  10.   
  11.                    //super();  
  12.   
  13.                    num= 60;  
  14.   
  15.                    System.out.println("fu run");  
  16.   
  17.          }  
  18.   
  19.          Fu(int  x)  
  20.   
  21.          {  
  22.   
  23.                    System.out.println("fu ...."+x);  
  24.   
  25.          }  
  26.   
  27.            
  28.   
  29. }  
  30.   
  31.    
  32.   
  33. class Zi extends Fu  
  34.   
  35. {  
  36.   
  37.          Zi()  
  38.   
  39.          {  
  40.   
  41.                      
  42.   
  43.                    super();  //指向默认的父类构造函数  
  44.   
  45.                    //super(4);//调用构造函数  
  46.   
  47.                    System.out.println("zi run");  
  48.   
  49.          }  
  50.   
  51.          Zi(int x)  
  52.   
  53.          {  
  54.   
  55.                    this();  
  56.   
  57.                    //super();  
  58.   
  59.                    //super(3);  
  60.   
  61.                    System.out.println("zi..."+x);  
  62.   
  63.          }  
  64.   
  65. }  
  66.   
  67.    
  68.   
  69. class  ExtendsDemo4  
  70.   
  71. {  
  72.   
  73.          public static void main(String[] args)   
  74.   
  75.          {  
  76.   
  77.                    Zi z = new Zi(0);  
  78.   
  79.                    System.out.println(z.num);  
  80.   
  81.          }  
  82.   
  83. }  
  84.   
  85.    
  86.   
  87. /*  
  88.   
  89. class Person  
  90.   
  91. {  
  92.   
  93.          private  String name;  
  94.   
  95.          Person(String name)  
  96.   
  97.          {  
  98.   
  99.                    this.name = name;  
  100.   
  101.          }  
  102.   
  103.    
  104.   
  105.          void show(){}  
  106.   
  107. }  
  108.   
  109. class Student extends Person  
  110.   
  111. {  
  112.   
  113.          Student(String name)  
  114.   
  115.          {  
  116.   
  117.                    super(name);  
  118.   
  119.          }  
  120.   
  121.          void method()  
  122.   
  123.          {  
  124.   
  125.                    super.show();  
  126.   
  127.          }  
  128.   
  129. }  
0 0
原创粉丝点击