一、介绍
继承是面向对象最显著的一个特性。继承是从已有的类中派生出新的类,新的类能吸收已有类的数据属性和行为,并能扩展新的能力。Java继承是使用已存在的类的定义作为基础建立新类的技术,新类的定义可以增加新的数据或新的功能,也可以用父类的功能,但不能选择性地继承父类。这种技术使得复用以前的代码非常容易,能够大大缩短开发周期,降低开发费用。
在面向对象程序设计中运用继承原则,就是在每个由一般类和特殊类形成的一般——特殊结构中,把一般类的对象实例和所有特殊类的对象实例都共同具有的属性和操作一次性地在一般类中进行显式的定义,在特殊类中不再重复地定义一般类中已经定义的东西,但是在语义上,特殊类却自动地、隐含地拥有它的一般类(以及所有更上层的一般类)中定义的属性和操作。特殊类的对象拥有其一般类的全部或部分属性与方法,称作特殊类对一般类的继承。
比如可以先定义一个类叫车,车有以下属性:车体大小,颜色,方向盘,轮胎,而又由车这个类派生出轿车和卡车两个类,为轿车添加一个小后备箱,而为卡车添加一个大货箱。
二、知识点介绍
1、继承概念
2、继承的定义及使用格式
3、继承注意事项
4、方法重写
三、上课对应视频的说明文档
1、继承概念
1.1、继承概述
继承是面向对象的核心特性,是面向对象的学习重点。同时继承是代码复用的重要方式,可以表示类与类之间的关系,是所有面向对象语言不可缺少的组成部分。
1.2、继承概念
当一个类的属性与行为均与现有类相似,属于现有类的一种时,这一个类可以定义为现有类的子类。
或者换成相反的角度来看,如果多个类具有相同的属性和行为,我们可以抽取出共性的内容定义父类,这时再创建相似的类时只要继承父类即可。
子类拥有父类的所有属性与方法,无需重新定义。并且可以直接使用非私有的父类成员。
从类与类之间的设计关系来看,子类必须属于父类的一种时,才会继承。
我们在完成一个庞大项目体系的时候,都是将共性的内容抽取出,后续构建过程是从各种父类“向外”扩散的。
下例展示了一个继承关系
图1-1 动物继承关系图
动物类可以有姓名、年龄的成员变量,可以有吃饭、睡觉的方法。
所有猫科与犬科均有动物的成员变量与成员方法,且猫科与犬科均属于动物,所以猫科与全科均可以继承动物类。
猫科可以在动物的基础上再添加抓老鼠的方法
犬科可以在动物的基础上再添加看门的方法
犬科与猫科仍可以继续出现子类,如波斯猫、巴厘猫、沙皮狗、斑点狗等,而其子类仍可以再出现该品种的特性。
2、继承定义及使用格式
2.1、继承定义
class 子类 extends 父类{
//父类的非私有方法与属性均继承过来
}
如:
父类的定义:
class Person{
private String name;
public void eat(){
System.out.println(“吃饭”);
}
get/set方法
}
子类继承父类的定义:
class Chinese extends Person{}
2.2、继承使用
继承关系的产生通常是为了定义出功能更为具体、更为强大的子类。所以,定义子类后,一般创建子类对象使用。子类可以直接使用父类非私有的成员变量与成员方法
(注:如果成员变量没有使用private修饰,则子类也可直接访问。)
子类的使用:
class Test{
public static void main(String[] args) {
Chinese c = new Chinese();
c.setName(“张大力”);
String name = c.getName();
System.out.println(name);//打印结果为张大力
c.eat(); //打印结果吃饭
}
3、继承注意事项
Java只支持单继承,不支持多继承。即只能有一个父类。
父类可以继续有父类。
所有类均有父类,只有Object类没有父类。
在所有使用父类类型的地方均可以传入其子类对象。
/*
* Animal的类
* 属性
* name
* age
* 行为
* 吃
* 睡
*/
public class Animal {
//成员变量
private String name;
private int age;
// //吃
// public abstract void eat(){
// System.out.println(“吃”);
// }
//睡
public void sleep(){
System.out.println("睡");
}
//-----------get/set-------------------
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;
}
}
/*
*定义一个猫类
* 属性
* name
* age
* kind
* 行为
* 吃
* 睡
* 抓老鼠
*/
public class Cat extends Animal{
private String kind;
// @Override
// public void eat(){
// System.out.println("猫吃鱼");
// }
//猫特有的功能 抓老鼠
public void catchMouse(){
System.out.println("抓耗子");
}
public String getKind() {
return kind;
}
public void setKind(String kind) {
this.kind = kind;
}
}
/*
*定义一个狗类
* 属性
* name
* age
* kind
* 行为
* 吃
* 睡
* 看门
*/
public class Dog extends Animal{
private String kind;
// @Override
// public void eat(){
// System.out.println("狗吃肉");
// }
//狗特有功能 看门
public void lookDoor(){
System.out.println("看门");
}
public String getKind() {
return kind;
}
public void setKind(String kind) {
this.kind = kind;
}
}
/*
* 自定义类型 家
*
* 地址
*
* 行为
* 在家吃饭
*/
public class Home {
private String address;
//动物在家吃饭
//在所有使用父类类型的地方均可以传入其子类对象。
public void eatAtHome(Animal a){
//调用Animal的eat方法
//a.eat();
}
//狗在在家吃饭
// public void eatAtHome(Dog dog){
// System.out.println("狗在家吃了");
// //调用狗的eat方法
// dog.eat();
// }
//猫在家吃饭
// public void eatAtHome(Cat cat){
// System.out.println("猫在假吃了");
// //调用猫的eat方法
// cat.eat();
// }
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
}
/**
* 测试家类
*/
public class Test {
public static void main(String[] args) {
// 创建Home对象
Home home = new Home();
// Animal a = new Animal();
// home.eatAtHome(a);
//在所有使用父类类型的地方均可以传入其子类对象。
Dog d = new Dog();
home.eatAtHome(d);
Cat c = new Cat();
home.eatAtHome(c);
}
}
4、方法重写
4.1、方法重写概念
当子类继承父类后,拥有了父类的成员并可以直接调用父类非私有方法。如果子类认为父类提供的方法不够强大,子类可以按照子类自身的逻辑重新定义继承过来的父类方法,这个重新定义一个方法的过程叫做方法重写。
(注:在学习完多态和抽象类后我们会对方法重写有更深的理解)
4.2、方法重写格式
子类中定义与父类一样的方法便将父类的方法重写了。此时,当创建子类对象,调用方法时,会调用子类重写后的方法。如:
子类中定义与父类一样的方法声明即是方法重写。
如:
父类定义:
public class Person{
private String name;
public void eat(){
System.out.println(“吃饭”);
}
get/set
}
子类定义:
public class Chinese extends Person{
@override //@override是用于强制规定当前定义的方法一定为重写的方法
public void eat() {
System.out.println(“按照中国的习惯,使用筷子吃”);
}
}
子类的使用:
public class Test{
public static void main(String[] args) {
Chinese c = new Chinese();
c.setName(“张大力”); //父类继承方法直接调用
String name = c.getName(); //父类继承方法直接调用
System.out.println(name); //打印结果为张大力
c.eat(); //方法重写后调用的为重写后的方法
//打印结果:按照中国的习惯,使用筷子吃
}
}
/**
* 自定义类型 人类
*
* 姓名 年龄
*/
public class Person {
String address;
private String name;
private int age;
public void eat(){
System.out.println("吃");
}
public void sleep(){
System.out.println("睡");
}
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;
}
}
/*
* 定义类型 学生类
*
* 姓名 年龄
*
* 继承
* 概念1 当定义一个类时,发现现有类与要定义的类类似,并且要定义的类属于现有类的一种时,
* 就可以将这个类定义为现有类的子类
*
* 子类拥有父类的所有属性与方法,无需重新定义。并且可以直接使用非私有的父类成员。
*
* 父类私用的成员变量 可以使用get/set方法 访问
* 父类私有的方法 没有办法直接方法 虽然继承了 但是相当于没有
*
* 子类可以有自己特有的属性和方法
*
* 方法重写
* 子类继承父类后,可以直接使用父类的非私有成员,但是如果觉得父类的成员方法不够强大,子类可以按照自身的逻辑
* 将继承过来的父类方法,进行重写(方法重写,方法复写,方法覆盖)
*
* 可以使用@Override来验证你的方法是不是重写方法。
*/
public class Student extends Person{
private String number;
public void method(){
System.out.println(address);
System.out.println(getName());
}
//重写父类eat方法
@Override
public void eat(){
System.out.println("学生吃学生套餐");
}
public String getNumber() {
return number;
}
public void setNumber(String number) {
this.number = number;
}
}
/*
* 测试继承后的Studnet
*/
public class Test {
public static void main(String[] args) {
//创建Studnet对象
Student s = new Student();
s.setName("柳柳");
s.setNumber("0900112");
s.eat();
// s.sleep();
String name = s.getName();
System.out.println(name);
System.out.println(s.getNumber());
System.out.println("-----------------");
//子类调用自己特有的方法
s.method();
}
}
4.3、Java中方法重写规则
子类重写方法时,在声明前加@Override可检测该方法是否为重写的方法
访问权限相同或子类方法访问权限更大(访问权限顺序public>默认)
class Fu{
void show(){}
public void method(){}
}
class Zi extends Fu{
public void show(){} //编译运行没问题
void method(){} //编译错误
}
方法名称必须相同
参数列表必须相同
返回值为基本类型时必须相同
返回值为引用类型时相同或子类小(了解)
/*
* 方法重写的注意事项
* 子类重写方法时,在声明前加@Override可检测该方法是否为重写的方法
* 访问权限相同或子类方法访问权限更大(访问权限顺序public>默认)
* 方法名称必须相同
* 参数列表必须相同
* 返回值为基本类型时必须相同
* 返回值为引用类型时相同或子类小(了解)
*/
public class Fu {
public void method(){
System.out.println(" 父类方法");
}
public int sum(){
return 0;
}
public Person get(){
return null;
}
}
public class Zi extends Fu{
//访问权限相同或子类方法访问权限更大(访问权限顺序public>默认)
@Override
public void method(){
System.out.println("子类方法");
}
//返回值为基本类型时必须相同
@Override
public int sum(){
return 100;
}
//返回值为引用类型时相同或子类小(了解)
@Override
public Student get(){
return null;
}
}