继承
1. 概念
- 继承是面向对象的三大特征之一, 可以使得子类具有父类的属性和方法,还可以在子类中重新定义,以及追加属性和方法;
- 当类与类之间存在is-a关系的时候,可以使用继承来描述这种关系;
2. 如何实现继承
- 通过extends关键字实现继承
- 格式: class 子类 extends 父类 { }
// 父类
class Father {
}
// 子类 继承 父类
class Son extends Father {
}
3. 继承的好处与弊端
① 好处
- 继承可以让类与类之间产生子父类关系,产生子父类后,子类则可以使用父类中非私有的成员。
- 提高了代码的复用性(多个类相同的成员可以放到同一个类中);
- 提高了代码的维护性(如果方法的代码需要修改,修改一处即可);
class Father {
public void show() {
System.out.println("show方法被调用");
}
}
class Son extends Father {
public void method() {
System.out.println("method方法被调用");
}
}
public class Demo {
public static void main(String[] args) {
//创建对象,调用方法
Father f = new Father();
f.show();
Son s = new Son();
s.method();
s.show();
}
}
② 弊端
- 继承让类与类之间产生了关系,类的耦合性增强了,当父类发生变化时子类实现也不得不跟着变化,削弱了子类的独立性;
4. 注意事项
- 在java中,类与类之间的继承只能是单继承;(既一个类,最多只能有一个直接的父类);
- 在java中,类的继承具有传递性;(既可以多重继承);
- 在java中,所有的类都直接或间接的继承了Object类;(既Object类是超类,基类);
- 在java中,继承的时候,应该符合 is-a的关系;(不能纯粹的为了得到某个功能而让不同类别的事物继承);
5. this&super关键字
- this:代表本类对象的引用
- super:代表父类存储空间的标识(可以理解为父类对象引用)
class Father {
private int id;
public Father(int id) {
this.id = id;
}
public void show() {
System.out.println("show方法被调用");
}
}
class Son extends Father {
private String name;
public Son(int id, String name) {
super(id);
this.name = name;
}
public void method() {
super.show();
System.out.println("method方法被调用");
}
}
6. 方法重写
① 概念
- 子类出现了和父类中一模一样的方法声明(方法名一样,参数列表也必须一样)
class Father {
public void show() {
System.out.println("父类中的show方法被调用");
}
}
class Son extends Father {
@Override
public void show() {
super.show();
System.out.println("子类中的show方法被调用");
}
}
② 方法重写的注意事项
- 私有方法不能被重写(父类私有成员子类是不能继承的)
- 子类方法访问权限不能更低(public > 默认 > 私有)
7. 修饰符
① package
- 概念: 包就是文件夹,用来管理类文件的;
- 定义格式: package 包名; (多级包用.分开)
- 例如:package com.heima.demo;
② import
- 使用不同包下的类时,使用的时候要写类的全路径,写起来太麻烦了为了简化带包的操作,Java就提供了导包的功能
- 格式: import 包名;
- 范例:import java.util.Scanner;
③ 权限修饰符
④ final
- 概念: final代表最终的意思,可以修饰成员方法,成员变量,类
⑤ static
- 概念: static关键字是静态的意思,可以修饰【成员方法】,【成员变量
- 访问特点: 静态成员方法只能访问静态成员
8. 继承的练习
- 需求:定义老师类和学生类,然后写代码测试;最后找到老师类和学生类当中的共性内容,抽取出一个父类,用继承的方式改写代码,并进行测试
// 父类, 人类
class Person {
// 成员变量
private String name;
private int age;
// 构造方法
public Person() {
}
public Person(String name, int age) {
this.name = name;
this.age = age;
}
// getter and setter
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
// 成员方法
public void eat(String food) {
System.out.println(name + "吃" + food);
}
}
// 老师类, 继承Person
class Teacher extends Person {
public Teacher() {
}
public Teacher(String name, int age) {
super(name, age);
}
// 重写eat方法
@Override
public void eat(String food) {
System.out.println(super.getName() + "老师吃" + food);
}
// 老师特有的, 教学方法
public static void teach() {
System.out.println("用爱成就每一位学生");
}
}
// 学生类, 继承Person
class Student extends Person {
public Student() {
}
public Student(String name, int age) {
super(name, age);
}
// 重写eat方法
@Override
public void eat(String food) {
System.out.println(super.getName() + "学生吃" + food);
}
// 学生特有的学习方法
public void study() {
System.out.println("好好学习, 天天向上");
}
}
public class MyExtends {
public static void main(String[] args) {
// 创建老师对象
Teacher t = new Teacher();
t.setName("张三丰");
t.setAge(88);
t.eat("小米粥");
t.teach();
System.out.println("----------");
// 创建学生对象
Student s = new Student("张无忌", 18);
s.eat("牛肉");
s.study();
}
}
运行结果: