4-继承
1.继承的语法格式
格式
class 子类名称 extends 父类名称{
}
被继承的这个类称为父类、 基类或者 超类
继承的这个类称为子类 或者 派生类
2. 继承的案例
父类:
package com.bobo.oop08;
/**
* 这是个Person类,抽取了 Student、Doctor、Police三个类的公共代码
* @author dpb
*
*/
public class Person {
public String name;
public int age;
public String gender;
public void sleep() {
System.out.println("sleep .... ");
}
}
Student,Police,Doctor三个子类
package com.bobo.oop08;
/**
* 这是一个学生类
* @author dpb
*
*/
public class Student extends Person{
public String stuNo; // 学生编号
public void study(){
System.out.println("study ....");
}
}
Police
package com.bobo.oop08;
/**
* 这是一个警察类
* @author dpb
*
*/
public class Police extends Person{
public String policeNo; // 警员编号
/**
* 抓坏人的方法
*/
public void catchBadGuys(){
System.out.println(".....");
}
}
Doctor
package com.bobo.oop08;
/**
* 这是一个医生类
* @author dpb
*
*/
public class Doctor extends Person{
public String doctorNum; // 医生编号
public String department; // 部门
public void savePeople(){
System.out.println("save ...");
}
}
3.继承的好处
- 简化了代码
- 提高了代码的可维护性
- 提高了扩展性
4.继承的缺点
开发设计思想:高内聚低耦合(尽量在一个类里面内聚,类和类之间的关系尽量保持独立)
继承后耦合性提高,牵一发动全身, 这个缺点不能改进,在Java中里面尽量不要使用继承
5. 继承的注意事项
- 继承是对一批类的抽象,类是对一批对象的抽象
- Java中只支持单继承,不支持多继承,但是支持多层继承
- 子类可以继承父类private修饰的属性和方法,但是不可见
- 子类不可以继承父类构造方法
- 子类出来继承父类的属性和方法以外,还可以添加自己的属性和方法

6. 怎么使用继承
继承的本质是什么? --> 简化代码
- 先写出所有的子类,观察子类共有的成员变量和成员方法
- 抽象出共同点,书写出父类
- 让子类区继承父类,并把子类中的共有属性删除
7.课堂案例
1、定义一个人类(姓名,年龄,性别,吃,睡) ,学生类继承人类(学号,班级,课程) ,老师类继承人类(工号,教龄,教书)
package com.bobo.oop09;
/**
* 姓名,年龄,性别,吃,睡
* @author dpb
*
*/
public class Person {
public String name;
public int age;
public String gender;
public void eat(){
System.out.println("Person.eat() ....");
}
public void sleep(){
System.out.println("Person.sleep() ...");
}
}
package com.bobo.oop09;
/**
* 老师类继承人类(工号,教龄,教书)
* @author dpb
*
*/
public class Teacher extends Person{
public String workNum;
public int schoolAge;
public String course;
}
package com.bobo.oop09;
/**
* 学生类继承人类(学号,班级,课程)
* @author dpb
*
*/
public class Student extends Person{
public String stuNo;
public String className;
public String course;
}
8. super关键字
super关键字可以理解为 父类对象,this关键字表示当前对象
当一个属性的使用没有添加this或者super关键字,那么他的查找顺序是 局部变量–>成员变量–>父类变量 如果还没有找到那么就会包编译异常。
被this修饰的变量,如果本类的成员变量中没有找到,同样也会去父类中查找
被super修饰的变量只会从父类中查找,如果父类中没有,而子类中存在,同样会报编译错误
super和this关键字访问成员的区别
成员变量
- this.成员变量
- super.成员变量 super 是不能访问私有的成员变量的,可以通过访问对应的共有方法实现
成员方法:
- this.成员方法
- super.成员方法
构造方法:
-
this(参数列表);
-
super(参数列表);
任何一个构造方法都默认的会在构造方法的第一句上写上 super(); 访问父类的无参构造方法
目的是初始化父类的成员变量
Constructor call must be the first statement in a constructor
super和this方法构造方法都必须出现在构造方法的第一句,this和super在方法构造方法的时候,二者是不能共存
static静态的上下文都是不能出现this和super的
案例代码:
package com.bobo.oop01;
public class Son extends Father{
/**
* 在子类中定义了一个和父类中同名的属性
* 子类中定义的同名的属性会覆盖掉父类中的属性
*/
public int num = 30;
public void show(){
// 局部变量会覆盖掉成员变量
//int num = 40;
// 输出局部变量
System.out.println("num:" + num);
// 输出成员变量
System.out.println("num:" + this.num);
// 输出父类的成员变量
System.out.println("num:" + super.num);
System.out.println(super.getAge());
eat();
}
public Son(){
// 在构造方法中,默认都会添加一句 super(); 而且必须是第一行
// Constructor call must be the first statement in a constructor
System.out.println("Son 子类构造器执行了...");
}
public Son(int num){
this();
//super(); 会在无参构造方法中执行 super(); 此处如果再执行一次就会出现两次初始化父类中成员变量的情况
}
}
package com.bobo.oop01;
public class Father {
public int num = 10;
private int age ;
public void eat(){
System.out.println("Father.eat ...");
}
public Father(){
System.out.println("Father 。。。。构造器执行了");
}
public int getAge() {
return age;
}
}
package com.bobo.oop01;
public class OOPDemo01 {
public static void main(String[] args) {
Son son = new Son();
son.show();
}
}
9. 访问权限修饰符
作用:表示被修饰的元素的访问权限
访问权限修饰符有四个: public protected [default] private
访问权限修饰符可以修饰的元素:
- 类 只有public、abstract和final能够修饰,或者不加【private和protected可以修饰内部类】
- 成员变量
- 成员方法
四个修饰符的特点
- public修饰的成员对一切类可见
- protected修饰的成员本包下面都可见,不同包下只有子类可见
- default修饰的成员仅对同包下面的可见
- private修饰的成员仅对本类可见
Java中的封装就是通过访问权限修饰符来实现的
访问权限修饰符的宽严的关系
public > protected > default > private
| public | protected | [default] | private | |
|---|---|---|---|---|
| 同一类中 | √ | √ | √ | √ |
| 同一包中子类、其它类 | √ | √ | √ | |
| 不同包中子类 | √ | √ | ||
| 不同包中其它类 | √ |
10. 方法的重写
如果从父类继承的方法不能满足子类的需求的情况下,可以对其进行改写,这个过程叫方法的覆盖(override),也称为方法的重写,子类中出现了和父类中一模一样的方法声明,,也称为方法的覆盖或者方法的复写。
方法的重写的规则
- 方法名称相同
- 参数列表相同
- 返回值类型相同或者是其子类
- 访问权限修饰符不能严于父类
方法重写的注意事项:
- 父类中的私有的方法不能重写的
- 构造方法不能被重写
- 子类重写父类方法时,访问权限不能更低
- 重载和重写的区别
面试题:
重载和重写的区别:
重载的定义:
- 同一个类中
- 方法名称相同
- 参数列表不同
- 和返回值及访问权限修饰符没有关系
| 位置 | 方法名 | 参数列表 | 返回值 | 访问权限修饰符 | |
|---|---|---|---|---|---|
| 方法重写 | 子类 | 相同 | 相同 | 相同或者子类 | 不能严于父类 |
| 方法重载 | 同类 | 相同 | 不相同 | 没有关系 | 没有关系 |
11. 课堂案例讲解
(1)设计一个User类,其中包括用户名、口令等属性以及构造方法(至少重载2个)。获取和设置口令的方法,显示和修改用户名的方法等。编写应用程序测试User类。
package com.bobo.oop05;
public class OOPDemo01 {
/**
* 设计一个User类,其中包括用户名、口令等属性以及构造方法(至少重载2个)。
* 获取和设置口令的方法,显示和修改用户名的方法等。编写应用程序测试User类。
* @param args
*/
public static void main(String[] args) {
User user = new User("admin","123");
System.out.println(user.getUserName());
System.out.println(user.getPassword());
}
}
class User{
private String userName;
private String password;
public User(){
}
public User(String userName,String password){
this.userName = userName;
this.password = password;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
12. final关键字
final关键字是 最终 的意思,可以修饰类,变量和方法
12.1 修饰类
该类就不能被继承
12.2 修饰变量
变量会变为常量,只能赋值一次,之后就不能改变了, final修饰的变量称为常量,常量名我们都大写,常量一般我们会声明为static
成员变量:在定义的同时必须给出初始值。
局部变量:可以在使用之前赋值

12.3 修饰方法
final修饰的方法,子类是不能重写该方法的!
Cannot override the final method from Person


本文详细介绍了Java中的继承概念,包括继承的语法格式、案例演示、继承的优点与缺点、使用注意事项等。并通过具体实例展示了如何利用继承简化代码、提高代码可维护性和扩展性。

被折叠的 条评论
为什么被折叠?



