博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
继承性
阅读量:6264 次
发布时间:2019-06-22

本文共 8195 字,大约阅读时间需要 27 分钟。

什么叫继承:
       
在程序中对已有的类进行扩展,称为继承。
       
概念的引出:例如:观察以下的程序,发现其问题:
class Person{
         private String name ;
         private int age ;
         public void setName(String name){
                   this.name = name ;
         }
         public void setAge(int age){
                   this.age = age ;
         }
         public String getName(){
                   return this.name ;
         }
         public int getAge(){
                   return this.age ;
         }
};
class Student{
         private String name ;
         private int age ;
         private String school ;
         public void setName(String name){
                   this.name = name ;
         }
         public void setAge(int age){
                   this.age = age ;
         }
         public void setSchool(String school){
                   this.school = school ;
         }
         public String getName(){
                   return this.name ;
         }
         public int getAge(){
                   return this.age ;
         }
         public String getSchool(){
                   return this.school ;
         }
};
       
此代码符合之前的设计思路,但是进一步观察,会发现以下问题,在Student
类中定义了三个属性,其中有两个属性已经在Person
中定义了,所以此时就发现代码重复太多了。那么现在就要使用继承的概念。
       
继承的基本格式:class 
子类 extends 
父类
class Person{
         private String name ;
         private int age ;
         public void setName(String name){
                   this.name = name ;
         }
         public void setAge(int age){
                   this.age = age ;
         }
         public String getName(){
                   return this.name ;
         }
         public int getAge(){
                   return this.age ;
         }
};
class Student extends Person{
         // 
如果什么都不定义的话,至少包含四个方法
};
public class Demo02{
         public static void main(String args[]){
                   Student stu = new Student() ;
                   stu.setName("
张三
") ;
                   stu.setAge(30) ;
                   System.out.println("
姓名:
"+stu.getName()+"
,年龄:
"+stu.getAge()) ;
         }
};
 
       
实际上子类可以拥有比父类中更多的属性或方法。所以此时直接在类中定义新的属性 
—— school
class Person{
         private String name ;
         private int age ;
         public void setName(String name){
                   this.name = name ;
         }
         public void setAge(int age){
                   this.age = age ;
         }
         public String getName(){
                   return this.name ;
         }
         public int getAge(){
                   return this.age ;
         }
};
class Student extends Person{
         // 
如果什么都不定义的话,至少包含四个方法
         private String school ;
         public void setSchool(String school){
                   this.school = school ;
         }
         public String getSchool(){
                   return this.school ;
         }
};
public class Demo03{
         public static void main(String args[]){
                   Student stu = new Student() ;
                   stu.setName("
张三
") ;
                   stu.setAge(30) ;
                   // 
此为子类自己的方法
                   stu.setSchool("
北京大学
") ;
                   System.out.println("
姓名:
"+stu.getName()+"
,年龄:
"+stu.getAge()+"
,学校:
"+stu.getSchool()) ;
         }
};
       
由此可见,子类确实增加了父类中的方法,扩展了父类中已有的功能。
 
但是一个子类不允许同时继承多个父类,它本身是一个单继承的关系。
 
父类中的所有私有操作实际上子类是全部继承了,只是采用了隐式的继承方式完成的,例如:各个私有属性,可以通过setter
getter
进行访问。
 
下面开始进一步完善Person
class Person{
         private String name ;
         private int age ;
         public Person(){
                   System.out.println("**************************") ;
         }
         public Person(String name,int age){
                   this.name = name ;
                   this.age = age ;
         }
         public void setName(String name){
                   this.name = name ;
         }
         public void setAge(int age){
                   this.age = age ;
         }
         public String getName(){
                   return this.name ;
         }
         public int getAge(){
                   return this.age ;
         }
         public String getInfo(){
                   return "
姓名:
"+this.name+"
,年龄:
"+this.age ;
         }
};
class Student extends Person{
         // 
如果什么都不定义的话,至少包含四个方法
         private String school ;
         public Student(){
                   System.out.println("---------------------------") ;
         }
         public void setSchool(String school){
                   this.school = school ;
         }
         public String getSchool(){
                   return this.school ;
         }
};
public class Demo05{
         public static void main(String args[]){
                   new Student() ;
         }
};
 
 
正常的规律:
       
没有老子,那来的自己呢???
       
如果想用子类,则必须先保证父初始化了。因为构造方法是为属性进行初始化的,所以必须先调用父类中的构造方法,但是默认情况下,找的是父类中的无参构造方法。
         public Student(){
                   // 
此处实际上默认隐含了一个
super()
,表示调用父类中的无参构造方法
                   super() ;
                   System.out.println("---------------------------") ;
         }
 
继续完善Student
类。
class Person{
         private String name ;
         private int age ;
         public Person(){
                   System.out.println("**************************") ;
         }
         public Person(String name,int age){
                   this.name = name ;
                   this.age = age ;
         }
         public void setName(String name){
                   this.name = name ;
         }
         public void setAge(int age){
                   this.age = age ;
         }
         public String getName(){
                   return this.name ;
         }
         public int getAge(){
                   return this.age ;
         }
         public String getInfo(){
                   return "
姓名:
"+this.name+"
,年龄:
"+this.age ;
         }
};
class Student extends Person{
         // 
如果什么都不定义的话,至少包含四个方法
         private String school ;
         public Student(){
                   // 
此处实际上默认隐含了一个
super()
,表示调用父类中的无参构造方法
                   super() ;
                   System.out.println("---------------------------") ;
         }
         public void setSchool(String school){
                   this.school = school ;
         }
         public String getSchool(){
                   return this.school ;
         }
         public String getStuInfo(){
                   return "
姓名:
"+getName()+"
,年龄:
"+getAge()+"
,学校:
"+this.school ;
         }
};
public class Demo06{
         public static void main(String args[]){
                   Student stu = new Student() ;
                   stu.setName("
张三
") ;
                   stu.setAge(30) ;
                   stu.setSchool("
北京大学
") ;
                   System.out.println(stu.getStuInfo()) ;
         }
};
 
在此代码之中存在了问题:
Person.class
         public String getInfo(){
                   return "
姓名:
"+this.name+"
,年龄:
"+this.age ;
         }
 
Student.class
         public String getStuInfo(){
                   return "
姓名:
"+getName()+"
,年龄:
"+getAge()+"
,学校:
"+this.school ;
         }
 
       
以上两部分代码相比较,可以发现:
· 
有部分内容重复了
· 
如果要是取得信息的话,是不是应该方法名称相同才好,感觉父类中定义的方法不够子类使。
 
方法的覆写:
       
子类可以定义与父类中方法名称完全相同的方法,参数的类型或个数也相同,此时就是方法的覆写。
class A{
         public void fun(){
                   System.out.println("Hello") ;
         }
};
class B extends A{
         // 
此处定义了一个与父类中方法名称相同的方法
         // 
所以此时称为方法的覆写
         public void fun(){
                   System.out.println("World!!!") ;
         }
};
public class Demo07{
         public static void main(String args[]){
                   B b = new B() ;
                   b.fun() ;
         }
};
       
如果方法被子类覆写了,则肯定最终找的是被覆写过的方法。
 
实际上覆写也是有要求:
       
在子类覆写父类方法的时候,被覆写的方法不能拥有比父类更严格的访问权限。
       
访问权限:public > default > private
`
那么现在使用此概念修改之前的代码,进一步完善Person
Student
类。
class Person{
         private String name ;
         private int age ;
         public Person(){
                   System.out.println("**************************") ;
         }
         public Person(String name,int age){
                   this.name = name ;
                   this.age = age ;
         }
         public void setName(String name){
                   this.name = name ;
         }
         public void setAge(int age){
                   this.age = age ;
         }
         public String getName(){
                   return this.name ;
         }
         public int getAge(){
                   return this.age ;
         }
         public String getInfo(){
                   return "
姓名:
"+this.name+"
,年龄:
"+this.age ;
         }
};
class Student extends Person{
         // 
如果什么都不定义的话,至少包含四个方法
         private String school ;
         public Student(){
                   // 
此处实际上默认隐含了一个
super()
,表示调用父类中的无参构造方法
                   super() ;
                   System.out.println("---------------------------") ;
         }
         public void setSchool(String school){
                   this.school = school ;
         }
         public String getSchool(){
                   return this.school ;
         }
         public String getInfo(){
                   return super.getInfo()+"
,学校:
"+this.school ;
         }
};
public class Demo08{
         public static void main(String args[]){
                   Student stu = new Student() ;
                   stu.setName("
张三
") ;
                   stu.setAge(30) ;
                   stu.setSchool("
北京大学
") ;
                   System.out.println(stu.getInfo()) ;
         }
};
 
覆写与重载的区别:
区别点
方法的覆写
方法的重载
概念上
方法名称相同,参数的类型或个数相同
方法名称相同,参数的类型或个数不同
范围
继承关系之中
发生在一个类中
特殊要求
覆写的时候被子类覆写的方法不能用有比父类更严格的访问权限
-
 
注意点:
       
关于方法覆写一定要明白,如果父类中定义的方法是一个私有方法,则子类中在定义重名方法的时候不叫覆写。
class Demo{
         private void fun(){
                   System.out.println("HELLO") ;
         }
         public void test(){
                   fun() ;
         }
};
class SDemo extends Demo{
         // 
实际上此时是在本类中新定义了一个方法
         void fun(){
                   System.out.println("hello") ;
         }
};
public class Demo12{
         public static void main(String args[]){
                   SDemo sd = new SDemo() ;
                   sd.test() ;
         }
};
 
super
关键字:
       super
关键字,在程序中明确的表示出了要调用父类的:
       
· 
构造方法
       
· 
属性
       
· 
普通方法
 
super
调用构造方法的时候,必须放在子类构造方法的首行
class Demo{
         public Demo(){
                   System.out.println("
父类中的无参构造。
") ;
         }
         public Demo(String name){
                   System.out.println("
父类中有一个参数的构造。
") ;
         }
};
class SDemo extends Demo{
         public SDemo(){
                   super() ;
         }
         public SDemo(String name){
                   super(name) ;
         }
};
 
public class Demo09{
         public static void main(String args[]){
                   SDemo sd = new SDemo("zhangsan") ;
         }
};
 
使用super
还可以调用父类中已经被子类覆写过的方法
class Demo{
         public Demo(){
                   System.out.println("
父类中的无参构造。
") ;
         }
         public Demo(String name){
                   System.out.println("
父类中有一个参数的构造。
") ;
         }
         public void fun(){
                   System.out.println("
父类中的方法。。。
") ;
         }
};
class SDemo extends Demo{
         public SDemo(){
                   super() ;
         }
         public SDemo(String name){
                   super(name) ;
         }
         public void fun(){
                   super.fun() ;
                   System.out.println("
子类中的方法。。。
") ;
         }
};
 
public class Demo10{
         public static void main(String args[]){
                   SDemo sd = new SDemo("zhangsan") ;
                   sd.fun() ;
         }
};
 
使用super
还可以直接找到父类中被子类覆盖的属性:
class Demo{
         public String name = "HELLO" ;
};
class SDemo extends Demo{
         public String name = "hello" ;
         public void fun(){
                   System.out.println(super.name) ;
                   System.out.println(name) ;
         }
};
public class Demo11{
         public static void main(String args[]){
                   SDemo sd = new SDemo() ;
                   sd.fun() ;
         }
};
 
super
this
的区别:
区别
super
this
范围
从子类找到父类中的内容
直接找到本类中的内容
属性
直接找到父类中的指定属性,不在子类中找
如果在本类中找到了属性,则使用,如果没有找到,则会从父类中找此属性
方法
直接调用父类中的方法
如果本类中有就调用,如果没有就找父类中的方法
构造
在子类构造方法的首行调用,表示调用父类中的构造。子类中至少有一个构造方法可以调父类构造
表示直接调用本类中的其他构造方法,但至少有一个构造方法是没有
this()
的,作为出口
特殊
-
this
表示当前对象
本文转自 李兴华 51CTO博客,原文链接:http://blog.51cto.com/lixinghua/91242,如需转载请自行联系原作者
你可能感兴趣的文章
Irony - 一个 .NET 语言实现工具包
查看>>
Java之Static静态修饰符详解
查看>>
修改weblogic部署的应用名称
查看>>
aaronyang的百度地图API之LBS云与.NET开发 Javascript API 2.0【基本地图的操作】
查看>>
Java Nio 多线程网络下载
查看>>
C++不让程序一闪而过
查看>>
C# 中的枚举类型 enum (属于值类型)
查看>>
[Debug] Use Snippets to Store Behaviors in Chrome DevTools
查看>>
【Java面试题】3 Java的"=="和equals方法究竟有什么区别?简单解释,很清楚
查看>>
通用性好的win2003序列号: (推荐先用这个里面的)
查看>>
Chromium Embedded Framework中文文档 (升级到最新的Chrome)
查看>>
WPF Command CanExecute 的执行逻辑
查看>>
更为快捷的Excel操作方式 快捷键 Alt使用技巧动画图解
查看>>
程序员们最易犯的10种错误
查看>>
面试必考题!你知道CSS实现水平垂直居中的第10种方式吗?
查看>>
超多惊喜!苹果 iPhone8 最新渲染图曝光
查看>>
你想要不想要?OPPO R11将搭配前后2000万像素镜头!
查看>>
Payara基金会发布全面支持MicroProfile 2.0的5.183版
查看>>
360金融宣布采用新会计准则 2018年前三季度净利11亿
查看>>
非洲小哥见到马云 竟然提了这样的要求?
查看>>