Java 继承
一、继承的概念
1.概念
- 继承是java面向对象编程技术的一块基石,因为它允许
创建分等级层次的类
。- 继承就是
子类继承父类的特征和行为
,使得子类对象(实例)具有父类的实例域和方法,或子类从父类继承方法,使得子类具有父类相同的行为
。- 继承简单可以理解为:对于已经投入使用的类,尽量不要进行修改。推荐定义一个新的类,来
重复利用其中共性内 容
,并且可以在新的类中添加和改动需要的信息。
子类会具有父类的一般特性,也会具有自身的特性
父类
又称:基类、超类
子类
又称:派生类
二、简单的继承案例代码
1.格式
class 父类 {
}
class 子类 extends 父类 {
}
2.简单的继承关系
(1)案例分析
讲师,助教,都属于教师,讲师和助教共有的信息抽取出来作为 教师 父类。讲师类,助教类继承 教师 类,作为子类。
(2)编码实现
//将 讲师 和 助教 共有的信息抽取出来,编写 教师 父类
class Teacher {
String name;
String sex;
}
//编写 讲师 类并继承 教师 类,并且添加自己独有的行为(方法)讲课
class Lecturer extends Teacher{
public void lecture(){
System.out.println("讲师讲课");
}
}
//编写 助教 类并继承 教师 类,并且添加自己独有的行为(方法)辅导
class Assistant extends Teacher{
public void coach(){
System.out.println("助教辅导");
}
}
三、详细的继承知识整理
1.继承的三种类型
1.java语言是
单继承
,一个类只能继承自一个类
2.java语言可以多重继承
3.一个子类的父类只有一个
,但是一个父类可以有多个子类
2.继承的特性
(1) 子类可以拥有父类
非private的
属性和方法
(2) 子类可以拥有自己的属性和方法,即子类可以对父类进行扩展
(3) 子类可以用自己的方式实现父类的方法(重写Override)
。
(4) Java 的继承是单继承,但是可以多重继承。这是 Java 继承区别于 C++ 继承的一个特性。
(5) 提高了类之间的耦合性(继承的缺点,耦合度高就会造成代码之间的联系越紧密,代码独立性越差)。
3.继承的关键字
(1)extends关键字
在 Java 中,类的继承是单一继承,也就是说,
一个子类只能拥有一个父类
,所以extends 只能继承一个类
。
java.lang.Object类是所有类的最高公共父类
,一个类没有继承的关键字,则默认继承Object类
public class Person {
String name;
String sex;
public void eat() {}
public void sleep() {}
}
public class Student extends Person{
//即使子类不编写代码,也会用拥有父类所有非private的属性和方法
}
(2)implements关键字
使用
implements 关键字
可以变相的使java具有多继承
的特性,使用范围为类继承接口的情况,可以同时继承多个接口
(接口跟接口之间采用逗号分隔)。
public interface A {
public void aa();
public void bb();
}
public interface B {
public void aa();
}
public class C implements A,B {
}
(3)super关键字
通过
super关键字来实现对父类成员的访问
,用来引用当前对象的父类。
class A{
int a;
public void a(){}
}
class B extends A{
int a;
public void a(){}
public void test(){
this.a = 11;//调用自己的成员变量
super.a = 22;//调用父类的成员变量
this.a();//调用自己的成员方法
super.a();//调用父类的成员方法
}
}
(4)final关键字
final 关键字声明类
可以把类定义为不能继承的
,即最终类。
final class 类名{}
final 关键字修饰方法
,该方法不能被子类重写.
权限修饰符 final 返回值类型 方法名(){}
4.重写(override)
重写:override(覆盖、覆写)
在继承中,子类与父类的方法名称一样,参数列表也一样,但是
方法体不同
,称为方法的重写。
class Fu {
public void method(){
System.out.println("这是父类方法");
}
}
public class Zi extends Fu {
//Override注解可以检测重写方法是否符合规范,可以不写但是不推荐
@Override
public void method(){
System.out.println("这是子类方法");
}
}
5.构造方法
1.
子类构造方法中默认带有 super()调用父类构造方法
,所以一定要先调用父类构造方法
,后执行子类构造方法
2.可以通过super关键字在子类调用父类的重载构造
3.父类构造方法的调用必须是子类构造方法的第一条语句
,一个子类构造方法只能调用一个父类构造方法
4.只有子类构造方法才能调用父类构造方法
class ConstructorTest {
public static void main(String[] args) {
Zi z = new Zi();
}
}
//运行结果为:
父类无参构造方法
父类有参构造方法
子类构造方法
父类、子类的代码 ↓ ↓ ↓
class Fu {
public Fu(){
System.out.println("父类无参构造方法");
}
public Fu(int num){
this();//使用this关键字调用其它构造方法
System.out.println("父类有参构造方法");
}
class Zi extends Fu {
public Zi(){
//super();可以不写,编译器默认包含,如果调用了其它构造方法,则默认super()失效
super(20);
System.out.println("子类构造方法");
}
}
【注意】
1.
子类构造方法必须继承一个父类构造方法
2.出现了继承关系,编译器默认继承父类构造方法
3.子类默认构造方法和子类中的super()都为隐式
(可以不使用super关键字调用)
4. 如果要调用父类其它构造方法则必须使用super关键字调用
5.如果想调用两个父类构造方法
,则必须在父类另外一个构造方法中,使用this关键字
调用其它构造方法
6.父子类间成员变量的访问
//定义父子类
class Fu {
int numFu = 10;
int num = 100;//这是父子类重名变量
}
class Zi extends Fu{
int numZi = 10;//这是父子类重名变量
int num = 200;
}
知识点在注释
public class FieldTest {
public static void main(String[] args) {
//首先对子类父类创建对象,以供下文比较
Fu f = new Fu();//父类对象
Zi z = new Zi();//子类对象
//使用子类对象和父类对象,都可以输出父类的numFu
System.out.println(f.numFu);
System.out.println(z.numFu);
//但是只能使用子类对象输出numZi
System.out.println(z.numZi);
//如果父子类存在同名变量时
//等号左侧是哪个类,就会使用哪个类的成员变量,
//如果找不到继续向上(父类)寻找
System.out.println(f.num);//输出父类num
System.out.println(z.num);//输出子类num
//父类不会知道谁继承了它,但是子类一定知道继承了谁
}
}
7.父子类间成员方法的访问
子类方法的访问权限
必须大于等于
父类方法的权限修饰符
子类方法的返回值类型
必须小于等于
父类方法的返回值类型
class Fu {
public void methodFu(){System.out.println("这是父类方法");}
//这是父子类重名方法
Object method(){
System.out.println("这是父类重名方法");
return null;
}
}
class Zi extends Fu {
public void methodZi(){System.out.println("这是子类方法");}
//这是父子类重名方法
@Override
public String method(){
//子类的访问权限(public)大于父类的访问权限(default)
//子类的返回值类型(String)小于父类的返回值类型(Object)
String str = "这是子类重名方法";
return null;
}
}
知识点在注释
public class MethodTest {
public static void main(String[] args) {
Zi z = new Zi();//创建子类对象
z.methodFu();//父类对象访问父类方法
z.methodZi();//子类对象访问子类方法
//使用子类对象访问父子类重名方法时
//创建的对象是谁就优先使用谁,找不到就继续向上(父类)寻找
String str = z.method();
//使用的子类对象所以首先寻找子类中的 method()
}
}