我在上海乐字节学习java的第二十二天(持续更新中)

引出继承

//老师

class Teacher

{

String name;

int age;

String level;//级别

public void sleep(){}

}

//学生

class Student

{

String name;

int age;

String sn;//学号

public void sleep(){}

}

//公司雇员

class Employee

{

String name;

int age;

String hireDate;//入职时间

public void sleep(){}

}

问题:上述Teacher、Student、Employee三个类中存在着共同的代码,解决代码重复的问题。

//将多个类共同的信息提取出来

public class Person

{

String name;

int age;

public void sleep(){}

}

父类:存放共性(共同的特征(状态/行为))。
子类:存放特性(自己特有的特性(状态/行为))
从该例子,我们发现,继承关系解决了代码冲符的问题。

我在上海乐字节学习java的第二十二天(持续更新中)_第1张图片

//将多个类共同的信息提取出来

class Person

{

String name;

int age;

public void sleep(){}

}

//老师

class Teacher extends Person

{

String level;//级别

}

//学生

class Student extends Person

{

String sn;//学号

}

//公司雇员

class Employee extends Person

{

String hireDate;//入职时间

}

继承关系

什么是继承关系:
基于某个父类对对象的定义加以拓展,而产生新的子类定义,子类可以继承父类原来的某些定义,也可以增加原来父类所没有的定义,或者覆写父类中的某些特性。
从面向对象的角度上说:继承是一种从一般到特殊的关系,是种“is a”的关系,即子类是对父类的拓展,是一种特殊的父类, 比如:狗是动物的一种特殊情况,狗属于动物。

我在上海乐字节学习java的第二十二天(持续更新中)_第2张图片

在Java语言中,存在多个类的时候我们使用"extends"关键字来表示子类和父类之间的关系。
语法格式: 在定义子类的时候来表明自己需要继承拓展于哪一个父类。
public class 子类类名 extends 父类类名
{
编写自己也有的状态和行为
}

在Java中,类和类之间的继承关系只允许单继承,不允许多继承。 也就是说一个类A,只能有一个父类,不能出现类A同时继承于类B和类C。但是Java中允许多重继承。 如:上图动物分猫狗,猫狗又细分为具体不同品种的狗。
Java中除了Object类外, 每一个类都有一个直接的父类。如:class Student extends Person{ },此时Student类的父类是Person类。Object是Java语言的根类,所以Person的父类是Object。
Object要么是一个类的直接父类,要么是间接父类。

继承关系的作用:

  • 解决了代码重复的问题;
  • 真正的作用,表现出一个体系。

子类继承父类之后,可以拥有父类的某一些状态和行为(子类复用了 父类的功能或状态)。
子类到底继承了父类的哪些成员(根据访问修饰符来判断:)
1):如果父类中的成员使用public修饰 ,子类继承
2):如果父类中的成员使用protected修饰子类也继承,即使父类和子类不在同一个包中;
3):如果父类和子类在同一个包中,此时子类可以继承父类中缺省修饰符的成员;
4):如果父类中的成员使用private修饰,子类打死都继承不到。因为private只能在本类中访问;
5):父类的构造器子类也不能继承,因为构造器必须和当前的类名相同。

方法覆盖

场景:
子类拓展了父类,可以获得父类的部分方法和成员变量。可是当父类的某个方法不适合于子类本身的特征时,此时怎么办?
如企鹅(Penguin)和鸵鸟(Ostrich)是鸟类中的一个特殊品种,所以企鹊/鸵鸟类是鸟类的一个子类,但是鸟类有飞翔的功能,但
是对应企鹅/鸵鸟,飞翔的行为显然不适合于它。
此时怎么办??

//鸟类

class Bird

{

public void fly(){

System.out.println("自由飞翔!");

}

}

//企鹅

class Penguin extends Bird

{

public void fly(){//覆盖父类方法

System.out.println("飞不起来!");

}

}

//方法覆盖

class OverrideDemo 

{

public static void main(String[] args) 

{

//创建企鹅对象并调用其飞翔的方法

Penguin p = new Penguin();

p.fly();

}

}

方法覆写的原则(一同两小一大) : override
一同:
1.实例方法签名必须相同。 (方法签名=方法名+方法的参数列表)
两小:
2.子类方法的返回值类型是和父类方法的返回类型相同或者是其子类。 即子类可以返回一个更加具体的类型。
3.子类方法声明抛出的异常类型和父类方法声明抛出的异常类型相同或者是其子类。
子类方法中声明抛出的异常小于或等 于父类方法声明抛出异常类型;
子类方法可以同时声明抛出多个属于父类方法声明抛出异常类的子类(RuntimeException类型除外)
一大:
④子类方法的访问权限比父类方法访问权限更大或相等。
private修饰的方法不能被子类所继承也就不存在覆盖的概念。
判断是否是覆写方法的必杀技: @Override标签 :若方法是覆写方,在方法前或上贴上该标签,编译通过,否则,编译出错。
只有方法存在覆盖的概念,字段没有覆盖。
方法覆盖解决的问题:当父类的某一个行为不符合子类具体的特征的时候,此时子类需要重新定义父类。

方法重载和方法覆盖(方法重写)的区别:
方法重载: Overload
方法重写: Override
批判,本身二者一点关系都没有,仅仅只是因为名字很像
方法重载: Overload
**作用:解决了同一个类中,相同功能的方法名不同的问题。
既然是相同的功能,那么方法的名字就应该相同。
规则:两同一不同
同类中,方法名相同,方法参数列表不同(参数类型,参数个数参数顺序)。**
方法重写: Override
**作用:解决子类继承父类之后可能父类的某一个方法不满足子类的具体特征,此时需要重新在子类中定义该方法,并重写法体。
规则:一同两小,一大
一同:父类和子类的方法签名是相同的,所以建议:直接拷贝父类中方法的定义到子类中再重写方法体。**

你可能感兴趣的