一、继承的概念
继承(inheritance)机制是面向对象程序设计中使代码可以复用的最重要的手段,它允许程序员在保持原有类特性的基础上进行扩展,增加功能。这样产生的新类,称派生类(或子类),被继承的类称基类(或父类)。继承呈现了面向对象程序设计的层次结构,体现了由简单到复杂的认知过程。之前接触的复用都是函数复用,继承是类设计层次的复用
下面我们通过生活中的一些例子来说明继承(以人、学生、教师、警察之间的继承关系为例)
这里学生、警察、教师他们都是人,所以他们有一些共同的属性将这些属性抽取出来,封装为一个类为人(父类),子类首先是人(所以要继承父类人的属性),然后才有自己特有的属性才成为学生,警察,教师
1、基本概念
(1)保持已有类的特性而构造新类的过程称为继承(inheritance)
(2)已有的类称为父类 或超类
(3)继承实现的新类称为子类(派生类)
二、java中的继承
1、Java中继承的语法:
[ 类修饰符 ] class 子类名 extends 父类名 {
类体 body
}
extends :关键字,表示扩展、继承的意思,extends前面是子类名,后面跟父类名。
说明:在子类体中,只需要写新增部分,继承部分不需要写
class teacher{ //声明一个teacher类为父类
String name; //定义父类的成员变量name、age
int age;
void show(){ //定义父类成员方法,将成员变量输出
System.out.println(name);
System.out.println(age);
}
}
class Student extends teacher { //声明一个Student类为子类并继承父类
}
public class myfirst {
public static void main(String[] args) {
System.out.println("学生");
Student student=new Student(); //声明一个Student类的实例对象student
student.name="Tom"; //子类调用父类的成员变量name并赋值
student.age=19; //子类调用父类的成员变量age并赋值
student.show(); //子类调用父类的成员方法show
}
}
要点:
在继承中:
子类可以得到父类的属性和方法。 继承来的
子类可以添加新的属性和方法。 超越继承
子类可以重新定义父类的属性和方法。
2、继承原则
1、子类继承父类的成员变量
2、子类继承父类除构造方法以外的成员方法因为父类构造方法创建的是父类对象,子类必须声明自己的构造方法,创建子类自己的对象。
3、子类不能删除父类成员。
4、子类可以增加自己的成员变量和成员方法。
5、子类可以重定义父类成员。
3、子类对父类成员的访问权限
1、子类继承了父类的成员,但并一定都可以使用。
2、子类只能访问父类非私有成员,即子类只能访问父类 public 和 protected 成员,不能访问父类的private成员
3、但子类对象的内存中是有父类中定义的私有成员的,即子类继承了父类的私有成员,只是不能使用。
4、继承却不能使用,该怎么做呢? 可以通过父类公有成员方法访问父类私有成员
三、this与super
- 子类对象的属性和方法实际上包括两部分:
在父类定义的,可以用super来引用
自己新添加的,用this来引用
- super指代的是父类对象,this是当前对象。
- 从父类带过来的也是子类的一部分,所以如果在父类和子类中没有重名的话,实际上都可以用this来引用。
- 如果有重名的属性或方法,则需要用super和this来区分,super引用父类部分,this引用子类自己新定义的属性或方法。
this主要有三种用法: (1)用this来引用当前对象的成员变量或成员方法。
(2)用this来调用类中的另一个构造方法。
(3)把this当做参数传递给其他方法。
super主要有两种用法: (1)引用父类的成员变量或成员方法。
(2)调用父类的构造方法。
重点介绍super调用父类的构造方法:
父类的构造方法不能够被继承,但在子类的构造方法体中,可以使用super调用父类的构造方法
class A{
protected int a;
public A(){
a=0; }
public A(int new_a){
a=new_a; }
}
class B extends A{
private int b;
public B(){
super();
b=0; }
public B(int new_a,int new_b){
super(new_a);
b=new_b; }
}
说明:
1、对父类构造方法的调用必须放在子类构造方法的第一条语句,以对继承部分进行初始化。
2、如果子类构造方法的第一条语句没有显式地调用父类构造方法,那么父类的不带参数的构造方法super()会被自动作为第一条语句来调用。
3、子类对象的初始化顺序:
- 首先通过调用父类的构造方法或父类的不带参数的构造方法初始化继承的部分
- 其次初始化自己新增部分
四、子类方法的覆盖和属性隐藏
1、覆盖
- 如果父类成员适用于子类,则子类不需要重新定义父类成员,此时子类继承了父类的成员变量和成员方法,子类对象引用的是父类定义的成员变量,调用的是父类定义的成员方法。
- 如果从父类继承来的成员不适合于子类,子类不能删除它们,但可以重定义它们,扩充父类成员方法的功能,使父类成员能够适应子类新的需求。
要点
实现对父类方法的覆盖,必须注意以下几点:
1、完全相同的方法名。
2、完全相同的参数列表。
3、完全相同类型的返回值。
三个条件有一个不满足,就不是方法的覆盖,而是子类自己定义的与父类无关的方法,父类的方法未被覆盖,因而仍然存在。
子类的print方法有一部分代码与父类相重叠,如何简化不写?
如果在子类中要调用父类被覆盖的方法,怎么办?
- 调用父类被覆盖的方法格式如下:
- super.方法名(注意super点出方法名)
- 这也是super的第二种用法,即引用父类的成员
注意:方法覆盖时,子类方法不能缩小父类方法的访问权限。 比如:父类的方法如果是 protected ,子类方法只能是 protected 或者 public
“覆盖”与“重载”的比较
- “覆盖”与“重载”均是Java“多态” 的技巧之一。
- “重载”:它是在相同类内,定义名称相同,但参数个数或类型不同的方法,如此Java便可依据参数的个数或类型,调用相对应的方法。
- “覆盖”:它是在子类当中,定义名称、参数个数与类型均与父类相同的方法,用以改写父类里方法的功用。
2、属性隐藏
子类可以定义与父类同名的属性,称为属性隐藏。也就是说子类可以重新定义父类的属性。
class A{
protected int a;
protected String m="object A: ";//***
public A(){
a=0; }
public A(int new_a){
a=new_a; }
public void print(){
System.out.println(m+a); } }
class B extends A{
private int b;
public String m="object B: ";//***
public B(){
super();
b=0; }
public B(int new_a,int new_b){
super(new_a);
b=new_b; }
}
要点:
属性隐藏:子类中出现父类中同名属性的现象称为属性的隐藏
调用属性的规则:先在当前类中找,如果没有再到其父类中找,以此类推。
那么子类访问父类隐藏的属性?
五、访问控制符
六、类变量、实例变量与局部变量
- 定义在类体内且在方法外的变量称为成员变量
- 定义在方法内的变量称为局部变量
- 类的成员变量分为2种: 一种是类变量,一种是实例变量。
- 定义成员变量时,若变量前有关键字static,则称为类变量,若没有static关键字,则称为实例变量。
总结:
继承原理实际上是一个普适原理,如果没有继承,我们的生物世界就会永远在生物链的底端徘徊,就不会出现如此丰富的生态世界。继承是发展的一部分,只有不断继承旧的、成熟的东西,才会发展出更新的、更先进的东西,否则,我们就会在原地踏步,永不重复。
因此在程序设计中,继承带来的好处:一是可减少程序设计的错误;二是做到了代码复用,简化和加快了程序设计,提高了工作效率
通过继承的学习,我们重温立下的誓言:
至此今天的学习就到此结束了,笔者在这里声明,笔者写文章只是为了学习交流,以及让更多学习读者少走一些弯路,节省时间,并不用做其他用途,如有侵权,联系博主删除即可。感谢您阅读本篇博文,希望本文能成为您编程路上的领航者。祝您阅读愉快!