Java基类和派生类-程序员宅基地

技术标签: Java  派生类  基类  

   从外部看来,派生类是一个与基类具有相同接口的新类,或许还会有一些额外的的方法和域 。但继承并不仅仅是类的复用。当创建了一个派生类的对象时,该类包含了一个基类的子对象。这个子对象和你用基类直接创建的对象没有什么两样。二者的区别在于,后者来自于外部,而基类的子对象来自于派生类对象的内部。对基类的子对象初始化时至关重要的,而且也只有一种方法来保证这一点,那就是在派生类的构造器中调用基类的构造器,而基类的构造器具有执行基类初始化所需的所有能力和知识。

      在无参构造器时, java会自动在派生类的构造器中插入对基类的构造器的调用。

    

Java代码
  1. public class Humans {     
  2.     Humans(){  
  3.         System.out.println("我是人!");  
  4.     }  
  5.       
  6. }  

   

Java代码 
  1. public class Student extends Humans{  
  2.   
  3.     Student(){  
  4.         System.out.println("我是学生!");  
  5.     }  
  6.   
  7. }  

 

Java代码
  1. public class test {  
  2.     public static void main(String args[]){  
  3.           new Student();  
  4.     }  
  5. }  

 输出结果为:

      我是人!

     我是学生!

可以发现,总是基类的构造器先被初始化。

但是当构造器有参数时,那就必须使用关键字super现实地编写调用基类构造器的代码,并且匹配适当的参数列表。

Java代码 
  1. public class Humans {  
  2.       
  3.     private String name;  
  4.   
  5.     Humans(String name){  
  6.         System.out.println("我是叫"+name+"的人");  
  7.     }  
  8.   
  9.     public String getName() {  
  10.         return name;  
  11.     }  
  12.   
  13.     public void setName(String name) {  
  14.         this.name = name;  
  15.     }  
  16.   
  17. }  

 

Java代码
  1. public class Student extends Humans{  
  2.       
  3.     private String name;  
  4.   
  5.     Student(String name){  
  6.         super(name);  
  7.         System.out.println("我是学生!");  
  8.     }  
  9.   
  10.     public String getName() {  
  11.         return name;  
  12.     }  
  13.   
  14.     public void setName(String name) {  
  15.         this.name = name;  
  16.     }  
  17. }  

 

Java代码
  1. public class test {  
  2.     public static void main(String args[]){  
  3.         new Student("zhangsan");  
  4.     }  
  5. }  

 输出结果:

我是叫zhangsan的人

我是学生!

如果注释掉上面的super(name);将会报错。原因是派生类必须调用基类构造器。因为实例化派生类时,基类也会被实例化,如果不调用基类的构造器,基类将不会被实例化,所以派生类没有调用基类构造器会报错。

 

但是如果Humans的代码变成这样就不会错。如下代码:

Java代码
  1. public class Humans {  
  2.       
  3.     private String name;  
  4.   
  5.     Humans(){  
  6.         System.out.println("我是人!");  
  7.     }  
  8.     Humans(String name){  
  9.         System.out.println("我是叫"+name+"的人");  
  10.     }  
  11.   
  12.     public String getName() {  
  13.         return name;  
  14.     }  
  15.   
  16.     public void setName(String name) {  
  17.         this.name = name;  
  18.     }  
  19.   
  20. }  

 

Java代码
  1. public class Student extends Humans{  
  2.       
  3.     private String name;  
  4.       
  5.     Student(String name){  
  6.         //super(name);  
  7.         System.out.println("我是学生!");  
  8.     }  
  9.   
  10.     public String getName() {  
  11.         return name;  
  12.     }  
  13.   
  14.     public void setName(String name) {  
  15.         this.name = name;  
  16.     }  
  17. }  

 

Java代码
  1. public class test {  
  2.     public static void main(String args[]){  
  3.         new Student("zhangsan");  
  4.     }  
  5. }  

 输出结果为:

        我是人!

        我是学生!

原因是,如果基类有一个无参的构造器,就算派生类不用super显示调用基类的构造函数,编译器也会自动

去调用基类的无参构造函数。

所以上面的代码不会报错,输出结果也不是

        我是叫zhangsan的人

        我是学生!

而是

        我是人!

        我是学生!

派生类继承了基类的所有public和protected属性和方法,代码如下:

Java代码
  1. public class Humans {  
  2.       
  3.     public String sex;  
  4.       
  5.     protected int age ;  
  6.       
  7.     private String name;  
  8.   
  9.   
  10.     Humans(String sex,String name,int age){  
  11.         this.sex = sex;  
  12.         this.name = name;  
  13.         this.age = age;  
  14.     }  
  15.   
  16.     public String getName() {  
  17.         return name;  
  18.     }  
  19.   
  20.     public void setName(String name) {  
  21.         this.name = name;  
  22.     }  
  23.   
  24. }  

 

Java代码
  1. public class Student extends Humans{  
  2.       
  3.     Student(String sex ,String name,int age){  
  4.         super(sex,name,age);  
  5.     }  
  6. }  

 

Java代码
  1. public class test {  
  2.     public static void main(String args[]){  
  3.         Student s = new Student("男","zhangsan",10);  
  4.         System.out.println(s.sex);  
  5.         System.out.println(s.name);  
  6.         System.out.println(s.age);  
  7.     }  
  8. }  

 上面的System.out.println(s.name);会报错,因为name是private属性,如需访问,采用get方法:

 

Java代码
  1. System.out.println(s.getName());  

输出结果为:

zhangsan

10 

 

如果派生类定义了和基类一样的属性或方法,将覆盖基类的属性和方法。如将student改为如下代码:

Java代码
  1. public class Student extends Humans{  
  2.       
  3.     public String sex;  
  4.       
  5.     protected int age ;  
  6.       
  7.     private String name;  
  8.       
  9.     Student(String sex ,String name,int age){  
  10.         super(sex,name,age);  
  11.     }  
  12.       
  13.     public String getName() {  
  14.         return name;  
  15.     }  
  16.   
  17.     public void setName(String name) {  
  18.         this.name = name;  
  19.     }  
  20. }  

 输出结果为:

null

null

0

因为只有基类的属性在构造时赋值了,派生类的没有,当访问这些属性时,访问的是派生类的属性,所以全为null或者0。

只有当派生类的属性也被实例化时,才会得到属性的值。代码改为如下:

Java代码
  1. public class Student extends Humans{  
  2.       
  3.     public String sex;  
  4.       
  5.     protected int age ;  
  6.       
  7.     private String name;  
  8.       
  9.     Student(String sex ,String name,int age){  
  10.         super(sex,name,age);  
  11.         this.sex = sex;  
  12.         this.name = name;  
  13.         this.age = age;  
  14.     }  
  15.       
  16.     public String getName() {  
  17.         return name;  
  18.     }  
  19.   
  20.     public void setName(String name) {  
  21.         this.name = name;  
  22.     }  
  23. }  

 

输出结果为:

zhangsan

10 

 

要注意的是,super必须在构造器的最前面,不然会报错

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/KingOfOnePiece/article/details/50504977

智能推荐

linux内核配置选项详解_内核压缩模式有哪些 kernel gzip-程序员宅基地

文章浏览阅读1.7k次。linux配置选项详解 内核的配置选项有很多,一般情况下大部分选项都可以使用默认值,因此并不需要了解它们所代表的意义;但是某些应用场合需要将内核剪裁的足够小,这就需要我们知道各个选项的意义了。即使不考虑内核剪裁的因素,当我们打算深入了解某一个子系统时,也需要从该子系统的配置选项入手(可以从该子系统代码目录下的各个Kconfig文件入手),掌握各个代码的关系,避重就轻的进行代码分析。_内核压缩模式有哪些 kernel gzip

Python一行代码搞定炫酷可视化,你需要了解一下Cufflinks_python一行代码搞定炫酷可视化,你需要了解一下cufflinks!-程序员宅基地

文章浏览阅读1.1k次。前言学过Python数据分析的朋友都知道,在可视化的工具中,有很多优秀的三方库,比如matplotlib,seaborn,plotly,Boken,pyecharts等等。这些可视化库都有自己的特点,在实际应用中也广为大家使用。plotly、Boken等都是交互式的可视化工具,结合Jupyter notebook可以非常灵活方便地展现分析后的结果。虽然做出的效果非常的炫酷,比如plot..._python一行代码搞定炫酷可视化,你需要了解一下cufflinks!

c语言多线程http,c语言实现HTTP断点续传-程序员宅基地

文章浏览阅读419次。断点续传大致分了三个步骤。1、寻找文件已经下载到的指针位置。long FileLocate(char* path){FILE *fp; long last;if((fp=fopen(path,"ab+"))==NULL){printf("can not open %s\n",path);return 0;}else{fseek(fp,0L,SEEK_END);last=ftell(fp);fclo..._c 断点续传

es6的默认参数赋值与rest参数与扩展运算符_es6 扩展默认赋值-程序员宅基地

文章浏览阅读209次。<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>Title</title></head><body><div></div><div></div><div></div><script type="text/javas._es6 扩展默认赋值

机器学习实战 第3章 决策树_log(prob,2)-程序员宅基地

文章浏览阅读171次。1.决策树k-近邻算法可以完成很多分类任务,但是它最大的缺点就是无法给出数据的内在含义,决策树的主要优势就在于数据形式非常容易理解。优点:计算复杂度不高,输出结果易于理解,对中间值的缺失不敏感,可以处理不相关特征数据。缺点:可能会产生过度匹配问题。适用数据类型:数值型和标称型。 2.信息增益划分数据集的大原则是:将无序的数据变得更加有序。在划分数据集之前之后信息..._log(prob,2)

如何在线查看.mmap格式文件_mmap在线-程序员宅基地

文章浏览阅读1.2w次,点赞7次,收藏5次。一、在线查看.mmap格式文件步骤打开百度脑图,地址http://naotu.baidu.com点击【新建脑图】---->【打开】---->【选择本地文件】百度脑图查看.mmap格式文件还是有一些小问题的,.mmap上带着的文件文件阅读不了-..._mmap在线

随便推点

网站如何做seo优化_网站seo优化 需要做什么-程序员宅基地

文章浏览阅读5.3k次。随着时代的发展,千家万户都有了互联网,跟着潮流,人们都会在网上购物写东西,作为一名优化学者在网站建设项目策划,浅谈网站的急剧增加导致竞争网站优化变得日益困难。很多网站建设几年时间都没有什么排名,也很难展示在用户的眼前,无法给企业带来利益。造成这样的问题主要有哪几点呢?第一点:网站建设好后虽然一直在优化,但没有效果,没有排名。那么如何解决这两个问题,半年时间把网站排名到首页呢?第二点:网站建设好..._网站seo优化 需要做什么

ViewStub用法-程序员宅基地

文章浏览阅读2.4k次。在开发应用程序,会在运行时动态根据条件来决定显示哪个View或某个布局。那么最通常的想法就是把可能用到的View都写在上面,先把它们的可见性都设为View.GONE。这样的做法的优点是逻辑简单而且控制起来比较灵活。但是它的缺点就是,耗费资源。 推荐的做法是使用Android.view.ViewStub,ViewStub是一个轻量级的View,它一个看不见的,不占布局位置,占用资源非常_viewstub用法

ffmpeg常用指令_-acodec aac -ar 44100 -strict-程序员宅基地

文章浏览阅读139次。ffmpeg常用指令多媒体视频处理工具FFmpeg有非常强大的功能包括视频采集功能、视频格式转换、视频抓图、给视频加水印等给视频加水印_-acodec aac -ar 44100 -strict

vivado:mixed level sensitive and edge triggered event controls are not supported for synthesis_[synth 8-434] mixed level sensitive and edge trigg-程序员宅基地

文章浏览阅读5.1k次,点赞9次,收藏7次。环境:vivado2018.2如下主要部分代码里的always块报错:[Synth 8-434] mixed level sensitive and edge triggered event controls are not supported for synthesisalways@(posedge clk or rst) begin ...代码内容endstackoverflow上的解释大致为:Mixed sensitive list of levels and edges is not_[synth 8-434] mixed level sensitive and edge triggered event controls are no

平衡小车——编码器原理及其使用_平衡小车中编码器怎么接线-程序员宅基地

文章浏览阅读1.7w次,点赞49次,收藏455次。感觉用在平衡小车上的编码器相关的博文和资料都超级多的,不慌不慌_平衡小车中编码器怎么接线

mysql-odbc.rpm_LinuxAS5.0下安装mysql-connector-odbc的rpm包-程序员宅基地

文章浏览阅读246次。Linux AS5.0下安装mysql-connector-odbc的时候提示如下:#rpm -ivh mysql-connector-odbc-3.51.12-2.2.i386.rpm warning: mysql-c首页 → 数据库技术背景:阅读新闻Linux AS5.0下安装mysql-connector-odbc的rpm包[日期:2008-09-20]来源:Linux社区作者:Linux编..._mysql-connector-odbc-version.arch.rpm

推荐文章

热门文章

相关标签