Skip to content

day01 【继承、抽象类、综合案例】

今日内容介绍

java
继承及其特点
this/super
方法重写
抽象类

开题 复习

0.1 定义一个类

java
public class 类名{
    //成员变量
    //成员方法
}
注意:类名约定俗称写的英文,but首字母是大写的,后面每个单词的首字母要大写。一定要遵循。
举例:
public class Dog{
   String name;
   int age;

   //成员方法
   public void eat(){
       System.out.println("狗吃狗粮~");
   }

}

0.2 通过类创建对象

java
类是模拟事务的一种形象,它是抽象的,需要创建对象来进行具体体现。
格式:
   数据类型  对象名 = new 类名();
比如 创建dog
   Dog dog = new Dog();
调用方法
   dog.eat();
调用属性
   dog.name="小白";

0.3 封装

java
成员变量加了private.隐藏成员变量,外界无法直接访问。
先要赋值就要提供 setXxx方法,想要获取提供getXxx()。
变量的访问有个原则:就近原则。
public class Dog{
   private String name;
   private int age;

   public void setName(String name){
       this.name = name;
   }
   public String getName(){
     return name;
   }
   ...

   //成员方法
   public void eat(){
       System.out.println("狗吃狗粮~");
   }
}
this关键字有什么用:
  区分了成员变量和局部变量。
this含义:
  代表 谁调用就是谁。

0.4 构造方法

java
构造方法的作用:
   初始化对象的,主要是初始化对象中的成员变量。
构造方法的特点:
   方法名和类名是一样的;
   没有返回值,连void的没有。
构造方法注意事项:
   a:如果不写 系统会提供一个默认的无参构造。
   b: 如果写了构造,默认就没了。
   c: 建议写 无参和满参
   public class Dog{
   private String name;
   private int age;

   public Dog(){}

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

   public void setName(String name){
       this.name = name;
   }
   public String getName(){
     return name;
   }
   ...

   //成员方法
   public void eat(){
       System.out.println("狗吃狗粮~");
   }
}

0.5 this

java
this: 关键字
   用于区分成员变量和局部变量,代表当前的对象。
   谁调用这个方法,这个方法中的this就是谁。

0.6 private

java
可以修饰成员方法
可以修饰成员变量
可以修饰构造方法
   提供公共的访问方式。

第一章 继承

1.1 继承的概念【重点】

java
假如我们要定义如下类: 讲师类,班主任类和就业指导类,分析如下:
    1. 讲师类 属性:姓名,年龄,工资 行为:展示信息,讲课
    2. 班主任类 属性:姓名,年龄,工资 行为:展示信息,管理班级
    3. 就业指导类 属性:姓名,年龄,工资 行为:吃饭,展示信息,辅导就业

如果我们定义三个类,每个类都有姓名,年龄,工资,展示信息,代码重复了,需要把重复的代码单独定义到一个类中

在一个已知类A的基础上,创建新类B的过程,称之为继承
这里类A,称为父类,基类,超类
这里类B,称为子类,派生类
java
1.继承的概念:
	向上抽取,把相同的内容定义在父类中,子类完成继承,子类继承父类,就自动拥有了父类的属性和方法。

2.什么情况下使用继承(不能随便继承)?
    符合 is a 的关系
    xxx 是 yyy 的一种
    学生是人的一种 老师也是人的一种

3.继承的好处
   提高代码复用性
   提高代码维护性
   让类和类之间产生关系,学习多态的前提。
 继承的弊端:

1600477428408

1.2 继承的格式和代码体现【重点】

java
格式:
   先定义父类
	public class Fu{

	}
   再定义子类
    public class Zi extends Fu{}
  特点:
    子类自动拥有父类的属性和方法,
    A:Fu被称为父类 Zi被称为子类。
    B:子类对象可以使用父类中除了私有以外的所有属性和方法。

1640481443713

1640481487220

1640481546577

1640481636086

1640481681002

1640481707322

1640481728626

1640481771998

1640481809275

java
代码体现
 先父类 后子类 然后来个测试类

父类

java
public class Employee {
     String name;
     int age;
     int salary;

     public void show(){
         System.out.println("姓名:"+name+",年龄:"+age+",工资:"+salary);
     }
}

讲师类

java
package com.itheima.extends01;
/*
老师继承员工类 怎么做
 讲师
   有什么功能 讲课
 */
public class Teacher extends Employee{

    public void teaching(){
        System.out.println("老师正在讲解面向对象");
    }
}

班主任类

java
package com.itheima.extends01;
/*
班主任类
    继承员工

    特殊功能 管理班级
 */
public class Manager extends Employee{
    //特有功能  管理班级
    public void manageClass(){
        System.out.println("班主任正在管理班级");
    }
}

如何使用:测试类测试

java
package com.itheima.extends01;

public class Demo {


    public static void main(String[] args) {
        //创建讲师对象
        Teacher teacher = new Teacher();
        //如何给成员变量赋值呢?
        teacher.name = "法外狂徒张三";
        teacher.age=22;
        teacher.salary=10000;

        //调用方法
        teacher.show();//调用父类方法
        teacher.teaching();//调用子类特有方法
        // 自己测试一个班主任类
    }
}

总结

一旦子类继承了父类,就自动拥有了父类的成员属性和成员方法,可以直接调用。

还可以直接调用自己的功能。

1.3 java 继承的特点

java 只支持单继承,不支持多继承,但是可以多层继承。

1.4 在继承关系中 成员变量的访问特点 (重点是记住结论)

1.4.1 子类中定义的成员变量和父类中定义的成员变量 名字不一样

java
package com.itheima.extends02;
//父类
public class Fu {
    int num1 = 10000;
}
package com.itheima.extends02;
//子类
public class Zi extends Fu {
    int num2 = 10;

    public void show(){
        //子类在自己方法中能否使用自己的成员变量
        System.out.println(num2);
      // 子类自己没有 可以访问父类的成员变量
        System.out.println(num1);
    }
}
package com.itheima.extends02;
//测试类
public class Demo {
    public static void main(String[] args) {
        //创建子类对象
        Zi zi = new Zi();
        zi.show();
        //能不能直接方法
        System.out.println("访问子的num2:"+zi.num2);
        System.out.println("访问父定义的num1:"+zi.num1);
    }
}

成员属性访问特点:

子类自己有用自己的。

子类没有呢,找父类。

注意 子类能找父类的 父类找不到子类的。

1.4.2 子类中定义的成员变量和父类中定义成员变量 名字一样的

基于上面案例进行修改 父类中定义一个属性叫 num 子类中定义一个属性叫 num 甚至在成员方法中定义一个属性叫 num.

java
package com.itheima.extends03;
//父类
public class Fu {
 //在父类中定义一个成员变量num值是100
  int num = 100;
}

package com.itheima.extends03;
//子类
public class Zi extends Fu{
    //在子类中定义一个成员变量num值是200
    int num = 200;
    //普通方法
    public void show(){
        //在局部位置--方法中
        // 在方法中创建一个 属性叫num 值是300
        int num = 300;

        System.out.println(num);//遵循就近原则 结果是300
        // 访问本类中的成员变量
        System.out.println(this.num);
        // 访问父类中的成员变量
        System.out.println(super.num);
    }
}
package com.itheima.extends03;

public class Demo {
    public static void main(String[] args) {
        //创建子类对象
        Zi zi = new Zi();
        //调用show方法
        zi.show();
    }
}

成员属性访问特点:

子类自己有用自己的。

子类没有呢,找父类。

注意 子类能找父类的 父类找不到子类的。

子类中变量访问特点遵循就近原则!

​ 先从 方法内部找,方法内部有就使用。

​ 如果没有,就从本类的成员位置找,有就使用。

​ 如果没有,就去父类的成员位置找,有就使用,如果没有 继续往上....

问题:如果在局部位置我就想访问成员变量怎么玩?通过 this 关键字,访问本类中的成员。

问题:如果在局部位置我就想访问父类成员变量怎么玩?通过 super 关键字,访问父类中的成员。

1.5 在继承关系中 成员方法的访问特点

如果成员方法不一样 如果成员方法名一样

java
package com.itheima.extends04;

public class Fu {
    public void methodFu(){
        System.out.println("父类中的methodFu方法 ");
    }

    public void method(){
        System.out.println("父类中的 method方法");
    }

    public void driver(){
        System.out.println("开着桑塔纳,摇摇晃晃去东北。");
    }
}
package com.itheima.extends04;

public class Zi extends Fu{

    public void methodZi(){
        System.out.println("子类的方法");
    }

    public void method(){
        System.out.println("子类的方法 method");
    }

    public void driver(){
        System.out.println("开着五菱宏光,直角飘逸。");
    }
}
package com.itheima.extends04;

public class Demo {
    public static void main(String[] args) {
        //创建子类对象
        Zi zi = new Zi();
        zi.methodZi();//可以调用自己的方法
        zi.methodFu();//可以调用父类的方法
        //
        System.out.println("猜一猜 zi.method()结果是什么?");
        zi.method();
        zi.driver();
    }
}

结论:子类没有调用父类的,有调用自己的。如果出现了同名,优先使用子类的方法。

1.6 方法重写 (重点是可以实现)

什么叫方法重写:

text
在子类中出现了与父类一模一样的方法(返回值类型,方法名和参数列表一样),
会出现覆盖效果,也被称为重写或者复写。 Override 重写

怎么实现方法重写?

java
在子类中定义一个一模一样方法(返回值类型,方法名和参数列表)

怎么检验它是方法重写呢

jdk8 jar 包中,@Override 的注解可以进行检验。

1640487931431

跟方法重载不是一回事

什么是方法重载,在同一个类中,方法名称相同,参数列表不同。被称为方法的重载。

方法重载:调用方便。

快捷方式做方法重载

ctrl+o

方法重写的好处:沿袭了父类中的功能,又进行了增强。

方法重写注意事项:

父类中私有方法不能被重写。

子类重写的方法访问权限必须大于等于父类方法的权限。

​ public>protected>默认(default)>private

子类重写方法时一定保证,方法名 参数列表 返回值要一模一样。

1.7 手机案例---重写

1640491099069

OldPhone

java
package com.itheima.extends05Phone;
/*
 定义老款手机类
      成员方法 三个
          打电话
          发短信
          显示来电
 */
public class OldPhone {

    //打电话
    public void call(String who){
        System.out.println("正在给:"+who+"打电话....");
    }
    //发短信
    public void sendMessage(String who,String msg){
        System.out.println("给"+who+"发"+msg);
    }

    //来电显示
    public void show(){
        System.out.println("反诈中心110来电!!");
    }

}

NewPhone

java
package com.itheima.extends05Phone;
/*
新款手机继承老款手机
 */
public class NewPhone extends OldPhone {
      //发短信打电话 不需要重写
    // 来电显示需要重写

    @Override
    public void show() {
        super.show();// 调用父类中已经实现的代码
//        System.out.println("反诈中心110来电!!");
        //显示头像 显示位置
        System.out.println("哥们 你头像是个绿色的");
        System.out.println("哥们 你的位置在北京昌平");
    }
}

Demo

java
package com.itheima.extends05Phone;

public class Demo {
    public static void main(String[] args) {
        //测试老款手机
        OldPhone oldPhone = new OldPhone();

        oldPhone.call("响哥");
        oldPhone.sendMessage("博文","响哥想你了");
        oldPhone.show();

        //测试新款手机
        NewPhone newPhone = new NewPhone();
        newPhone.call("马保国");//执行的父类中定义好的
        newPhone.sendMessage("马大师","我要学习混元形意太极拳");//执行父类中定义好的
        newPhone.show();//执行重写后的
    }
}

第二章 继承中 构造的访问特点

2.1 父类构造对子类的意义

子类能继承父类的构造吗?

shell
不能!!
构造方法的名字跟类名是一致的,语法上来说 子类是无法继承父类构造的。
java
package com.itheima.extends06;

public class Fu {
    int num;

    public Fu(){
        System.out.println("父 空参....");
    }

    public Fu(int num){
        System.out.println("父 带参构造");
        this.num=num;
    }
}
package com.itheima.extends06;

public class Zi extends Fu{

    public Zi(){
        System.out.println("子 空参构造");
    }

    public Zi(int num){
        System.out.println("子 带参构造");
    }

}
package com.itheima.extends06;

public class Demo {

    public static void main(String[] args) {
        //创建一个子类对象
        Zi zi = new Zi();
        System.out.println("----------------");
        //创建一个子类对象 使用带参构造
        Zi zi1 = new Zi(10);
    }
}

1640502202690

我们通过写代码,观察发现。子类在构建对象的时候,都会默认调用父类的空参构造!

系统会默认给子类构造的第一行加上 super():代表初始化子类之前先初始化父类。

我们如果手动给出 super(..)语法,子类还会调用父类空参构造吗?不会。

我们做了一件事情,我们把父类中空参构造删掉。对子类有什么影响

1640502587194

为什么 在 public Zi()这里爆红?

因为我们不写 super(..)默认第一行是 super() 调用的父类的空参构造。

现在父类没有空参构造,不报错报什么?肯定报错。

如果报错,手动写一个调用存在的父类构造即可。

1640503009357

或者试用 this 语句调用本类中的构造,本类构造手动调用父类的带参构造(了解 因为我们不这样写。)

1640502869515

注意 this(..)super(..)都是作用于第一行 不能共存。

2.2 子类初始化的内存图

代码体现

Perosn 类

java
package com.itheima.extends07neicun;

public class Person {
    private String name;
    private int age;

    public Person() {
    }

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

    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 show(){
        System.out.println("name:"+name+" ...age:"+age);
    }
}

Student 类

java
package com.itheima.extends07neicun;

public class Student extends Person {
    private int score;//成绩
    public Student(){}

    public Student(String name, int age, int score) {
        super(name, age);//把name age属性值 给父类中的成员
        this.score = score;//把score给了本类中的成员
    }

    public int getScore() {
        return score;
    }

    public void setScore(int score) {
        this.score = score;
    }
}

测试类

java
package com.itheima.extends07neicun;

public class Demo {
    public static void main(String[] args) {
        Student student = new Student("力宏", 45, 100);
        System.out.println("------");
    }
}

1640504123163

子类中有成员变量,父类中也有成员变量

那么构建子类对象的时候,是先加载父类成员,还是子类成员变量。

父类。能不能以内存的形式来讲解!可以 ,那么属性什么时候被加载,加载顺序是什么样的,看 ppt 内存图。

1640503753014

通过内存图

强调一点 this 当前类对象的引用。super 是父类空间的标识(可以理解为是父类对象的引用).

第三章 抽象类

3.1 纵向提取思想的应用

假设有两个类 一个类是 猫 一个类是 狗

1640505346190

java
抽象:
  概念:说不清的,不具体的。功能要有,但是不给具体的实现。这种方法被称为抽象方法。
格式:
  public abstract 返回值类型 方法名();
什么是抽象类:在一个类中如果有抽象方法,那么这个类就必须是抽象类。
  public abstract class 类名{}
抽象类中抽象方法存在意义
   强制要求子类具备该功能,必须要实现该方法。

1640505582974

1640505624123

3.2 猫狗案例

1640505730201

Animal.java

java
package com.itheima.abstract01;

public abstract class Animal {

    //动物具备吃的功能但是 不能给出具体吃什么  所以吃的方法是抽象的方法
    public abstract void eat();

    // 动物具备喝水的功能
    public void drink(){
        System.out.println("喝水");
    }
}

Cat.java

java
package com.itheima.abstract01;
/*
Cat类继承了一个抽象类 Animal
   爆红 为甚呢?
      猫继承了动物,猫就具备了吃的功能
      猫是不是一个具体的动物
      应该具备 具体吃的功能呢
      必须要把 吃的方法实现
 */
public class Cat extends Animal{
    @Override
    public void eat() {
        System.out.println("猫吃鱼");
    }
}

Dog.java

java
package com.itheima.abstract01;
/*
  狗继承动物 也要重写 吃的方法
 */
public class Dog extends Animal{

    @Override
    public void eat() {
        System.out.println("狗啃骨头");
    }
}

Demo.java

java
package com.itheima.abstract01;

public class Demo {

    public static void main(String[] args) {
        //创建狗对象 吃吃喝喝
        Dog dog = new Dog();
        dog.eat();
        dog.drink();
        // 创建猫对象 吃吃 喝喝
        Cat c = new Cat();
        c.eat();
        c.drink();
    }
}

1640506217035

3.3 抽象类注意事项

  • 抽象类不能创建对象,如果创建,编译报错。通过子类对象。
  • 抽象类有构造,不能创建对象的原因,因为里面有抽象方法。避免调用的尴尬。
  • 抽象类构造的意义,就是提供给子类创建对象的时候,初始化父类成员。
  • 抽象类中可以没有抽象方法,但是抽象方法必须在抽象类中。抽象类中可以有 0-n 个抽象方法。
  • 抽象类的子类
    • 可以是重写抽象方法的子类。
    • 还可以是 没有重写方法的抽象类。

1640506584015

第四章 综合案例

1640507401067

1640507413878

text
步骤
  1:创建工程师类
      属性 工号 id  姓名 name
      setget方法
      空参和满参
      抽象方法 工作
  2:创建 抽象类 研发工程师  以及 维护工程师
     产生继承关系
     空参和满参构造
     不用实现
  3:javaee工程师 android工程师   网络维护工程师 硬件维护工程师
     产生继承关系
     空参和满参构造
     工作要实现,因为是具体的类。
  4:随便找一个具体类实现。

工程师类

java
package com.itheima.demo;
/*
创建工程师类
   抽象类
 */
public abstract class GongChengShi {
   //属性
    private int id;
    private String name;
  //空参满参
    public GongChengShi() {
    }

    public GongChengShi(int id, String name) {
        this.id = id;
        this.name = name;
    }
   //set get方法
    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    //抽象的工作方法
    public abstract void work();
}

研发工程师类

java
package com.itheima.demo;
//研发工程师继承 工程师
public abstract class YanFa extends GongChengShi{
   //写空参满参

    public YanFa() {
    }
    //作用是传递参数给父亲的成员变量
    public YanFa(int id, String name) {
        super(id, name);
    }
}

维护工程师类

java
package com.itheima.demo;
//维护工程师继承 工程师
public abstract class WeiHu extends GongChengShi{
   //写空参满参

    public WeiHu() {
    }
    //作用是传递参数给父亲的成员变量
    public WeiHu(int id, String name) {
        super(id, name);
    }
}

javaee 工程师类

java
package com.itheima.demo;
//javaEE工程师继承研发  要重写  因为是具体类
public class JavaEE extends YanFa{

    // 需要空参满参


    public JavaEE() {
    }

    public JavaEE(int id, String name) {
        super(id, name);
    }

    @Override
    public void work() {
        System.out.println("员工号:"+getId()+"名字为:"+getName()+"正在研发淘宝网站");
    }
}

Android 工程师类

java
package com.itheima.demo;
//Android工程师继承研发  要重写  因为是具体类
public class Android extends YanFa{

    // 需要空参满参


    public Android() {
    }

    public Android(int id, String name) {
        super(id, name);
    }

    @Override
    public void work() {
        System.out.println("员工号:"+getId()+"名字为:"+getName()+"正在研发淘宝APP端");
    }
}

网络维护工程师类

java
package com.itheima.demo;
//WangLuo工程师继承维护部  要重写  因为是具体类
public class WangLuo extends WeiHu{

    // 需要空参满参


    public WangLuo() {
    }

    public WangLuo(int id, String name) {
        super(id, name);
    }

    @Override
    public void work() {
        System.out.println("员工号:"+getId()+"名字为:"+getName()+"正在进行网络的维护");
    }
}

硬件维护工程师类

java
package com.itheima.demo;
//YingJian工程师继承维护部  要重写  因为是具体类
public class YingJian extends WeiHu{

    // 需要空参满参


    public YingJian() {
    }

    public YingJian(int id, String name) {
        super(id, name);
    }

    @Override
    public void work() {
        System.out.println("员工号:"+getId()+"名字为:"+getName()+"正在进行修理打印机");
    }
}

测试类

java
package com.itheima.demo;

public class Demo {

    public static void main(String[] args) {
        //创建一个JavaEE工程师
        JavaEE ee = new JavaEE(9527, "华安");

        ee.work();
    }
}

Released under the MIT License.