Java继承

简介: Java继承

继承
OOP语言主要的三大特征:继承 封装 多态

package com.bit.demo1;

class Animal {

String name;

 public void eat() {
     System.out.println(this.name + "  Animal eat");
 }

}

class Cat {

String name;

public void eat() {
    System.out.println(this.name + "  Cat eat");
}
String colour;

}

public class TestDemo {

public static void main(String[] args) {
    Cat cat = new Cat();
    cat.name = "dawanzi";
    cat.eat();
}

}

复制代码
上面这段代码就有点啰嗦,因为两个类里面都有name字段 和 eat方法

于是,就可以使用继承

什么是继承
继承就是进行共性提取,实现代码的复用,从而使代码更加简洁

语法格式:class 子类 extends 父类{

}

class Animal {

String name;

 public void eat() {
     System.out.println(this.name+"正在吃饭");
 }

}

class Cat extends Animal{

//此时Cat继承了Animal,Cat是子类,Animal是父类
//子类也叫派生类  父类也叫超类   基类
/*String name;

public void eat() {
    System.out.println(this.name + "  Cat eat");

}*/
String colour;

}

public class TestDemo {

public static void main(String[] args) {
    Cat cat = new Cat();
    cat.name = "dawanzi";
    cat.eat();
}

}

复制代码
子类继承了父类的什么?

事实上,子类继承了父类除构造方法以外的所有属性

注意:在Java里面使用 extends 只能继承一个父类(单继承)

class Animal {

String name;
 public void eat() {
     System.out.println(this.name + "  Animal eat");
 }

 private void sleep(){
     System.out.println(this.name + "  Animal sleep");
 }

}

class Cat extends Animal{

/*String name;

public void eat() {
    System.out.println(this.name + "  Cat eat");

}*/

int colour;

}

public class TestDemo {

public static void main(String[] args) {
    Cat cat = new Cat();
    cat.name = "dawanzi";
    cat.eat();
    cat.sleep();//err,要是将sleep方法改为public,Cat也是可以继承的的,但是sleep是prvate,只能在Animal这个类里面进行访问,所以会报错
}

}

复制代码
子类与父类中不存在成员变量同名的情况
class Base{

public int  a=1;
public int b=2;

}
class More extends Base{

int c=3;
int d=4;
public void func(){
    System.out.println(a);
    System.out.println(b);
    System.out.println(c);
    System.out.println(d);
}

}
public class test {

public static void main(String[] args) {
    More more = new More();
    more.func();
}

}
复制代码
子类与父类中存在成员变量同名的情况
class Base{

public int a=1;
public int b=2;

}
class More extends Base{

int a=3;

public void func(){
    System.out.println(a);//3
    System.out.println(b);//2
}

// public void func(){
// System.out.println(this.a);
// System.out.println("访问父类的a"+super.a);
// System.out.println(b);
// }
}
public class test {

public static void main(String[] args) {
    More more = new More();
    more.func();
}

}
//当子类与父类存在同名的变量名时,会优先调用子类1中的变量
//要是想要访问父类的a就要使用super关键字

复制代码
super
super指的是子类从父类继承过来的空间的地址

super的三种用法
super.data;

super.funnc();

super.构造方法;

class Base{

public int a=1;
public int b=2;

public void func1() {
    System.out.println("Base1:");
}

public void func2() {
    System.out.println("Base2:");
}

}
class More extends Base{

int a=3;

public void func1(int val) {
    System.out.println("More1:" + val);
}

public void func2() {
    System.out.println("More2:");
}

public void func(){
    func1();
    func1(10);
    func2();
    //super.func2();就是调用父类的方法
}

}
public class test {

public static void main(String[] args) {
    More more = new More();
    more.func();
}

}
//结果就是Base1:
//Base1:
//More1:10
//More2:
复制代码
注意:

1、Base的func1和More里面的func1构成了重载,这也说明了 重载不一定要在同一个类里面

2、当方法名一样时,还是优先调用子类自己的方法

3、要调用父类的方法还是直接super.func();

4、super和this都依赖于对象,所以都不能存在于static修饰的方法里面

5、super只能在子类构造方法中出现一次,并且不能与this一起出现

class Animal {

String name;
int age;

public Animal(String name, int age) {
    this.name = name;
    this.age = age;
}

public void eat() {
    System.out.println(this.name +"正在吃饭");
}

}

class Cat extends Animal{

String colour;

public Cat(String name, int age,String colour) {
    super(name, age);//super要放到第一行,先帮助完成父类的构造方法
    //只要光标放在报错的地方,按alt+enter就会自动创建了父类成员变量的super
    this.colour = colour;
}

@Override
public String toString() {
    return "Cat{" +
            "name='" + name + '\'' +
            ", age=" + age +
            ", colour='" + colour + '\'' +
            '}';
}

}

public class Test {

    public static void main(String[] args) {
        Cat cat = new Cat("小乖",12,"yellow");//使用构造方法完成初始化
        System.out.println(cat);//直接调用toString
    }

}
复制代码
this与super有什么区别?
this的特点:当前对象的引用

1.this(); //调用本类其他的构造方法

2.this.data(); // 访问当前类中的属性

3.this.func(); //调用本类的其他的成员方法

super :父类对象的引用(必须放到第一行)

1、super(); //调用父类的构造方法

2、super.data(); //访问父类的属性

3、super.func(); //访问父类的成员方法

相同点:

1、都是Java的关键字

2、都只能在非静态方法中使用,用来访问非静态的成员变量和方法,不能出现在static修饰的方法

不同点:

1、this是当前对象的引用,super表示子类从父类中继承的空间的地址

2、在非静态的方法中,this用来访问本类的方法和属性,super是用来访问父类继承下来的方法和属性

3、构造方法中一定会有super(……)的调用,用户不写编译器也会增加,而this(……)不写就没有

小总结:要想使用继承,要想看看父类有没有构造方法,要是没有,就加上extends配合super直接用,要是有构造方法,就用super(……),先帮助父类完成构造方法,再完成子类自己的构造方法

class Animal {

String name;
int age;
static {
    System.out.println("Animal的静态代码块");
}
{
    System.out.println("Animal的实例代码块");
}
public Animal() {
    System.out.println("Animmal的无参数构造方法");
}

public Animal(String name, int age) {
    this.name = name;
    this.age = age;
}

public void eat() {
    System.out.println(this.name +"正在吃饭");
}

}

class Cat extends Animal{

String colour;
static {
    System.out.println("Cat的静态代码块");
}
{
    System.out.println("Cat的实例代码块");
}

public Cat() {
    System.out.println("Cat的无参数构造方法");
}

public Cat(String name, int age,String colour) {
    super(name, age);
    this.colour = colour;
}
public class Test {

public static void main(String[] args) {
    Cat cat = new Cat();//实例化对象
    }
}

//Animal的静态代码块
//Cat的静态代码块
//Animal的实例代码块
//Animmal的无参数构造方法
//Cat的实例代码块
//Cat的无参数构造方法

复制代码
代码运行的顺序是:

父类和子类的静态代码块

父类的实例代码块和构造方法

子类的实例代码块和构造方法

在上面临的代码的基础上,修改main函数为

public static void main(String[] args) {

Cat cat = new Cat();
System.out.println("=======================");
Cat cat1 = new Cat();

}
//输出结果就是
//Animal的静态代码块
//Cat的静态代码块
//Animal的实例代码块
//Animmal的无参数构造方法
//Cat的实例代码块
//Cat的无参数构造方法
//=======================
//Animal的实例代码块
//Animmal的无参数构造方法
//Cat的实例代码块
//Cat的无参数构造方法
复制代码
在此说明了静态的创建在方法区,只会创建一次

访问修饰限定符
image-20220508223927620

private只能在同一个包的同一个类里面调用

default --->包访问权限 只能在同一个包里面访问

public不进行限制,在不在同一个包,在不在同一个类里面都行

protected
protected叫做受保护的,主要体现在封装上

protected在同一个包的同一个类或者不同的类里面都能访问,在不同的包的子类中也能访问

继承的方式
image-20220514222123504

多层继承实例
class Animal {

protected String  name;
public Animal(String name){  //没有返回值说明是构造方法
    this.name = name;
    System.out.println("Animal ");
}
 public void eat() {
     System.out.println(this.name + "  Animal eat");
 }

 private void sleep(){
     System.out.println(this.name + "  Animal sleep");
 }

}

class Cat extends Animal{

public Cat(String name) {
    super(name);
    System.out.println(this.name+"Cat");
}

}

class ChineseGardenCat extends Cat {

public ChineseGardenCat(String name) {   //直接alt+enter生成
    super(name);
}

}
public class TestDemo {

public static void main(String[] args) {
    ChineseGardenCat chineseGardenCat = new ChineseGardenCat("hhaha");//一层一层往父类上面调
}

}
复制代码
但是,多层继承不能无限继承下去,可以使用final来使类不能被继承

final 的用法
final int SIZE=10;//final修饰变量
final class B extends A { //final修饰类,使类不能被继承了

}
//final还可以修饰方法
复制代码
继承与组合
继承是is-a的关系,比如狗是一种动物

组合是has-a 或者 a part of 的关系,比如发动机 玻璃 坐垫都是汽车的一部分

组合就是将一个类的实例作为另一个类的字段

image-20220514224156905

School就包含了Student和Teacher的变量,学生和老师都是学校的一部分,这就是一个组合

// 轮胎类
class Tire{
// ...
}
// 发动机类
class Engine{
// ...
}
// 车载系统类
class VehicleSystem{
// ...
}
class Car{

private Tire tire; // 可以复用轮胎中的属性和方法
private Engine engine; // 可以复用发动机中的属性和方法
private VehicleSystem vs; // 可以复用车载系统中的属性和方法 

// 这就是组合
}
class Benz extend Car{
// 将汽车中包含的:轮胎、发送机、车载系统全部继承下来
}
复制代码
其实,更加建议使用组合,因为它更加灵活,更简单,更高效

目录
相关文章
|
3月前
|
Java 程序员
Java中的继承和多态:理解面向对象编程的核心概念
【8月更文挑战第22天】在Java的世界中,继承和多态不仅仅是编程技巧,它们是构建可维护、可扩展软件架构的基石。通过本文,我们将深入探讨这两个概念,并揭示它们如何共同作用于面向对象编程(OOP)的实践之中。你将了解继承如何简化代码重用,以及多态如何为程序提供灵活性和扩展性。让我们启程,探索Java语言中这些强大特性的秘密。
|
11天前
|
Java 开发者
在Java多线程编程中,创建线程的方法有两种:继承Thread类和实现Runnable接口
【10月更文挑战第20天】在Java多线程编程中,创建线程的方法有两种:继承Thread类和实现Runnable接口。本文揭示了这两种方式的微妙差异和潜在陷阱,帮助你更好地理解和选择适合项目需求的线程创建方式。
12 3
|
11天前
|
Java
在Java多线程编程中,实现Runnable接口通常优于继承Thread类
【10月更文挑战第20天】在Java多线程编程中,实现Runnable接口通常优于继承Thread类。原因包括:1) Java只支持单继承,实现接口不受此限制;2) Runnable接口便于代码复用和线程池管理;3) 分离任务与线程,提高灵活性。因此,实现Runnable接口是更佳选择。
24 2
|
11天前
|
Java
Java中多线程编程的基本概念和创建线程的两种主要方式:继承Thread类和实现Runnable接口
【10月更文挑战第20天】《JAVA多线程深度解析:线程的创建之路》介绍了Java中多线程编程的基本概念和创建线程的两种主要方式:继承Thread类和实现Runnable接口。文章详细讲解了每种方式的实现方法、优缺点及适用场景,帮助读者更好地理解和掌握多线程编程技术,为复杂任务的高效处理奠定基础。
23 2
|
11天前
|
Java 开发者
Java多线程初学者指南:介绍通过继承Thread类与实现Runnable接口两种方式创建线程的方法及其优缺点
【10月更文挑战第20天】Java多线程初学者指南:介绍通过继承Thread类与实现Runnable接口两种方式创建线程的方法及其优缺点,重点解析为何实现Runnable接口更具灵活性、资源共享及易于管理的优势。
22 1
|
2月前
|
Java 编译器
封装,继承,多态【Java面向对象知识回顾①】
本文回顾了Java面向对象编程的三大特性:封装、继承和多态。封装通过将数据和方法结合在类中并隐藏实现细节来保护对象状态,继承允许新类扩展现有类的功能,而多态则允许对象在不同情况下表现出不同的行为,这些特性共同提高了代码的复用性、扩展性和灵活性。
封装,继承,多态【Java面向对象知识回顾①】
|
22天前
|
Java 测试技术 编译器
Java零基础-继承详解!
【10月更文挑战第4天】Java零基础教学篇,手把手实践教学!
24 2
|
26天前
|
Java 编译器
在Java中,关于final、static关键字与方法的重写和继承【易错点】
在Java中,关于final、static关键字与方法的重写和继承【易错点】
20 5
|
26天前
|
Java
java继承和多态详解
java继承和多态详解
37 5
|
26天前
|
Java 编译器
【一步一步了解Java系列】:子类继承以及代码块的初始化
【一步一步了解Java系列】:子类继承以及代码块的初始化
20 3