Java基类和派生类
背景:对基类和派生类有更清晰的认识。
从外部看来,派生类是一个与基类具有相同接口的新类,或许还会有一些额外的的方法和域 。但继承并不仅仅是类的复用。当创建了一个派生类的对象时,该类包含了一个基类的子对象。这个子对象和你用基类直接创建的对象没有什么两样。
二者的区别在于,后者来自于外部,而基类的子对象来自于派生类对象的内部。对基类的子对象初始化时至关重要的,而且也只有一种方法来保证这一点,那就是在派生类的构造器中调用基类的构造器,而基类的构造器具有执行基类初始化所需的所有能力和知识。
示例
在无参构造器时, java会自动在派生类的构造器中插入对基类的构造器的调用。
public class Humans {
Humans(){
System.out.println("我是人!");
} }
public class Student extends Humans{ Student(){
System.out.println("我是学生!");
} }
public class test {
public static void main(String args[]){
new Student();
}
}
输出结果为:
我是人! 我是学生!
可以发现,总是基类的构造器先被初始化。
示例
但是当构造器有参数时,那就必须使用关键字super现实地编写调用基类构造器的代码,并且匹配适当的参数列表。
public class Humans { private String name; Humans(String name){
System.out.println("我是叫"+name+"的人");
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} }
public class Student extends Humans{ private String name; Student(String name){
super(name);
System.out.println("我是学生!");
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
}
}
public class test {
public static void main(String args[]){
new Student("zhangsan");
}
}
输出结果:
我是叫zhangsan的人 我是学生!
如果注释掉上面的super(name);将会报错。原因是派生类必须调用基类构造器。因为实例化派生类时,基类也会被实例化,如果不调用基类的构造器,基类将不会被实例化,所以派生类没有调用基类构造器会报错。
但是如果Humans的代码变成这样就不会错。如下代码:
public class Humans { private String name; Humans(){
System.out.println("我是人!");
}
Humans(String name){
System.out.println("我是叫"+name+"的人");
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} }
public class Student extends Humans{ private String name; Student(String name){
//super(name);
System.out.println("我是学生!");
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
}
}
public class test {
public static void main(String args[]){
new Student("zhangsan");
}
}
输出结果为:
我是人! 我是学生!
原因是,如果基类有一个无参的构造器,就算派生类不用super显示调用基类的构造函数,编译器也会自动去调用基类的无参构造函数。
所以上面的代码不会报错,输出结果也不是
我是叫zhangsan的人 我是学生!
而是
我是人! 我是学生!
示例
派生类继承了基类的所有public和protected属性和方法,代码如下:
public class Humans { public String sex; protected int age ; private String name; Humans(String sex,String name,int age){
this.sex = sex;
this.name = name;
this.age = age;
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} }
public class Student extends Humans{ Student(String sex ,String name,int age){
super(sex,name,age);
}
}
public class test {
public static void main(String args[]){
Student s = new Student("男","zhangsan",10);
System.out.println(s.sex);
System.out.println(s.name);
System.out.println(s.age);
}
}
上面的System.out.println(s.name);会报错,因为name是private属性,如需访问,采用get方法:
System.out.println(s.getName())
输出结果为:
男 zhangsan 10
示例
如果派生类定义了和基类一样的属性或方法,将覆盖基类的属性和方法。如将student改为如下代码:
public class Student extends Humans{ public String sex; protected int age ; private String name; Student(String sex ,String name,int age){
super(sex,name,age);
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
}
}
输出结果为:
null null 0
因为只有基类的属性在构造时赋值了,派生类的没有,当访问这些属性时,访问的是派生类的属性,所以全为null或者0。
只有当派生类的属性也被实例化时,才会得到属性的值。代码改为如下:
public class Student extends Humans{ public String sex; protected int age ; private String name; Student(String sex ,String name,int age){
super(sex,name,age);
this.sex = sex;
this.name = name;
this.age = age;
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
}
}
输出结果为:
男
zhangsan
10
要注意的是,super必须在构造器的最前面,不然会报错
最新文章
- MySQL 权限与安全
- 转:mysql根据经纬度查找排序
- macbook air 128g 磁盘清理
- 使用Topshelf创建Windows服务
- ArcGIS Runtime for Android 使用异步GP服务绘制等值线
- 李洪强-C语言7-C语言运算符
- Hadoop,HBase,Zookeeper源码编译并导入eclipse
- SQLite学习第03天:环境搭建
- 《鸟哥的Linux私房菜》读书笔记五
- HDU4453--Looploop (Splay伸展树)
- EZChart - 在线图表生成器
- Unity 图形处理(切分与拉伸)
- cefsharp解决闪烁
- 北京AI外包团队 祝大家2019事业有事,大吉大利!
- DIV+CSS详解
- 洗礼灵魂,修炼python(67)--爬虫篇—cookielib之爬取需要账户登录验证的网站
- 关于 使用python向qq好友发送消息(对爬虫的作用----当程序执行完毕或者报错无限给自己qq发送消息,直到关闭)
- poj2019 二维RMQ模板题
- 微信小程序使用三元表达式切换图片
- Java_Freemarker
热门文章
- Js基础---红宝书读书日记(1)-------基本类型和引用类型
- Centos下Nodejs+npm环境-部署记录
- linux-安装-源码安装
- python语言几个常见函数的使用
- 团队项目 NABCD分析java音乐播放器
- Eclipse+tomcat+MySQL搭建JavaWeb开发环境
- js和JQuery区别
- Exception while invoking TaskListener: Exception while invoking TaskListener: null
- [转载] Oracle在windows下面的自动备份以及删除今天的脚本..
- wx.downloadFile问题