Skip to content

day09.面向对象

java
课前回顾:
  1.可变参数:
    a.格式:  数据类型...变量名
    b.本质:  数组
    c.注意:
      参数列表中只能有一个可变参数,并且需要放到参数列表最后
  2.递归:
    a.概述:方法内部自己调用自己
    b.分类:
      直接递归:方法自己调用自己
      间接递归:多个方法互相调用
    c.注意:递归必须要有出口,不然会出现栈内存溢出
          即使有出口,也不能递归太多次
  3.数组操作:
    a.冒泡排序:相邻元素之间比较,大的往后,小的往前
    b.二分查找:每次比较都和数组的中间索引比较,每次干掉一半
      前提:数组必须是有序的 -> 升序
    c.对象数组:
      存的是对象,取的还是对象
    d.数组翻转:对称索引位置上的元素互换
  4.参数传递:
    a.参数为基本类型,传递的是值,不是变量本身
    b.参数为引用类型,传递的是地址值

今日重点:
  1.知道什么时候用继承
  2.知道继承的好处
  3.知道如何使用继承
  4.知道继承前提下成员的访问特点
  5.知道方法重写的使用场景
  6.知道继承的特点
  7.知道如何使用super关键字调用父类成员
  8.知道如何定义抽象类以及抽象方法
  9.知道如何实现抽象方法

第一章.继承

1.什么是继承

面向对象三大特征: 封装 [继承] 多态

java
1.父类怎么形成的:
  定义多个类的时候发现我们在反复定义相同的成员,此时我们就可以定义一个父类,将重复的成员都放到父类中,其他类
直接继承这个父类,就可以直接使用父类中抽取出来的非私有成员

2.怎么继承:
  子类 extends 父类

3.注意:
  a.子类可以继承父类中私有和非私有成员,但是不能直接使用父类中私有成员
  b.构造方法不能被继承
  c.静态方法可以继承,但是不能被重写

4.继承怎么学习:
  不要从"是否拥有"的层面来理解继承,要从"是否能使用"的层面来理解继承

5.问题:如果不使用继承,能不能完成功能?

       所以,继承是一种思想,是一种代码的设计理念,既然是设计理念,就可用可不用,只不过用了就比不用强,所以推荐使用
1742778859524

2.继承如何使用

java
1.定义一个父类,编写共性成员
2.定义一个子类,继承父类  -> 子类 extends 父类
3.创建子类对象,调用继承的成员
java
public class Employee {
    String name;
    int age;
    public void work(){
        System.out.println("员工都要工作");
    }

    private void eat(){
        System.out.println("员工都要吃饭");
    }
}
java
public class Teacher extends Employee{

}
java
public class Manager extends Employee{
}
java
public class Test01 {
    public static void main(String[] args) {
        Teacher teacher = new Teacher();
        teacher.name = "涛哥";
        teacher.age = 18;
        System.out.println(teacher.name+"..."+teacher.age);
        teacher.work();
        //teacher.eat();eat方法是私有的,继承之后也用不了

        System.out.println("===================");
        Manager manager = new Manager();
        manager.name = "萌姐";
        manager.age = 56;
        System.out.println(manager.name+"..."+manager.age);
        manager.work();
    }
}

3.继承中,成员变量和成员方法的访问特点

3.1 成员变量

3.1.1 子类和父类中的成员变量不重名:

java
public class Fu {
    int numFu = 100;
}
java
public class Zi extends Fu{
    int numZi = 10;
}
java
public class Test01 {
    public static void main(String[] args) {
        Zi zi = new Zi();
        System.out.println(zi.numZi);//自己的
        System.out.println(zi.numFu);//继承的

        System.out.println("======================");
        Fu fu = new Fu();
        System.out.println(fu.numFu);//父类自己的
        //System.out.println(fu.numZi);//不能使用子类的成员
    }
}

2.1.2.子类和父类中的成员变量重名

java
public class Fu {
    int num = 100;
}
java
public class Zi extends Fu {
    int num = 10;
}
java
public class Test01 {
    public static void main(String[] args) {
        Zi zi = new Zi();
        System.out.println(zi.num);//子类的

        System.out.println("=================");
        Fu fu = new Fu();
        System.out.println(fu.num);//父类的

        System.out.println("=================");

        //多态
        Fu fu2 = new Zi();
        System.out.println(fu2.num);//父类的
    }
}

继承前提下成员变量访问特点:看等号左边是谁,先调用谁中的成员变量,子类没有,找父类

2.2 成员方法

2.2.1.子类和父类中的成员方法不重名:

java
public class Fu {
   public void methodFu(){
       System.out.println("methodFu方法");
   }
}
java
public class Zi extends Fu {
    public void methodZi(){
        System.out.println("methodZi方法");
    }
}
java
public class Test01 {
    public static void main(String[] args) {
        Zi zi = new Zi();
        zi.methodZi();
        zi.methodFu();

        System.out.println("=================");
        Fu fu = new Fu();
        fu.methodFu();
        //fu.methodZi();不能调用子类特有的成员
    }
}

2.2.2.子类和父类中的成员方法重名

java
public class Fu {
   public void method(){
       System.out.println("父类中的method方法");
   }
}
java
public class Zi extends Fu {
    public void method(){
        System.out.println("子类中的method方法");
    }
}
java
public class Test01 {
    public static void main(String[] args) {
        Zi zi = new Zi();
        zi.method();//子类的method

        System.out.println("================");
        Fu fu = new Fu();
        fu.method();//父类的method

        System.out.println("================");
        Fu fu2 = new Zi();
        fu2.method();
    }
}

继承中成员方法访问特点:看 new 的是谁,先调用谁中的方法,子类没有,找父类

4.方法的重写

java
1.概述:
  子类中有一个和父类从方法名以及参数列表上一样的方法,叫做方法的重写
2.前提:
  必须有子父类继承关系
3.如何判断方法是否为重写的方法:
  在方法上加上一个注解 -> @Override
java
public class Fu {
    public void method(){
        System.out.println("我是父类中的method方法");
    }
}
java
public class Zi extends Fu{
    @Override
    public void method(){
        System.out.println("我是子类中的method方法");
    }
}
java
public class Test01 {
    public static void main(String[] args) {
        Zi zi = new Zi();
        zi.method();
    }
}

1.方法的重载:方法名相同,参数列表不同的方法-> 侧重同一个类

2.方法的重写:发生在继承中,子类中有一个和父类方法名以及参数列表一模一样的方法

4.1.注意事项

java
1. 子类方法重写父类方法,必须要保证权限大于等于父类权限。(权限修饰符)
   public -> protected -> 默认 -> private

2. 子类方法重写父类方法,方法名和参数列表都要一模一样。
3. 私有方法不能被重写,构造方法不能被重写,静态方法也不能重写
4. 子类重写父类方法之后,返回值类型应该是父类方法返回值类型的子类类型
   一般情况下,子类重写父类方法之后,都一样
5.私有方法,静态方法可以继承但是不能被重写,构造方法不能被继承,也不能被重写
JAVA
/**
 * String 有一个父类 Object
 * Object是所有的父类
 */
public class Fu {
    public void method(){
        System.out.println("我是父类中的method方法");
    }

    public String method02(){
        return null;//返回null没有任何含义,仅仅是为了不让方法报错
    }
}
java
public class Zi extends Fu {
    @Override
    public void method(){
        System.out.println("我是子类中的method方法");
    }

    @Override
    public String method02(){
        return null;//返回null没有任何含义,仅仅是为了不让方法报错
    }
}

4.2.使用场景

java
1.方法重写的使用场景:主要是增强父类某个功能,对父类方法进行升级改造
1742787133818
java
public class OldPhone {
    public void call(){
        System.out.println("打电话");
    }

    public void message(){
        System.out.println("发短信");
    }

    public void show(){
        System.out.println("显示手机号");
    }
}
java
public class NewPhone extends OldPhone{
    @Override
    public void show(){
        System.out.println("显示手机号");
        System.out.println("显示归属地");
        System.out.println("显示头像");
    }
}
java
public class Test01 {
    public static void main(String[] args) {
        OldPhone oldPhone = new OldPhone();
        oldPhone.call();
        oldPhone.message();
        oldPhone.show();
        System.out.println("====================");
        NewPhone newPhone = new NewPhone();
        newPhone.call();
        newPhone.message();
        newPhone.show();
    }
}

第二章.super 和 this

1.继承中构造方法的特点

java
1.特点:
  创建子类对象时,先初始化父类(不是说new父类对象,而是先调用父类无参构造方法)
2.原因:
  构造方法第一行默认会有一个super(),不写也有
  super()代表的就是父类无参构造方法
java
public class Fu {
    public Fu(){
        System.out.println("我是父类无参构造");
    }
}
java
public class Zi extends Fu{
    public Zi(){
        super();
        System.out.println("我是子类无参构造");
    }

    public Zi(int i){
        super();
        System.out.println("我是子类有参构造");
    }
}
java
public class Test01 {
    public static void main(String[] args) {
        Zi zi = new Zi();
        System.out.println("========");
        Zi zi1 = new Zi(10);
    }
}

2.super 和 this 的具体使用

java
1.super关键字:代表的是父类引用
2.this关键字:代表的是当前对象
3.super和this主要体现在调用上:
  super:可以调用父类成员
  this:可以调用当前对象的成员

2.1 super 的具体使用

java
1.概述:super代表的是父类引用
2.作用:主要调用父类成员
3.使用:
  a.调用父类构造方法:在子类的构造中使用
    super() 调用父类无参构造
    super(实参) 调用父类有参构造

  b.调用父类成员变量:在子类中使用
    super.成员变量名

  c.调用父类成员方法:在子类中使用
    super.成员方法名()
java
public class Fu {
    int num = 10;
    public Fu(){
        System.out.println("父类无参构造");
    }

    public Fu(int num){
        System.out.println("父类有参构造");
    }

    public void method(){
        System.out.println("父类method方法");
    }
}
java
public class Zi extends Fu{
    int num = 100;
    public Zi(){
        super();//调用父类无参构造
        System.out.println("子类无参构造");
    }

    public Zi(int num){
        //调用父类有参构造
        super(10);
        System.out.println("子类有参构造");
    }

    public void method(){
        System.out.println(num);//子类的num
        System.out.println(super.num);//父类的num
        super.method();//调用父类的method
        System.out.println("子类method方法");
    }
}
java
public class Test {
    public static void main(String[] args) {
        Zi zi = new Zi();
        System.out.println("============");
        Zi zi1 = new Zi(10);
        System.out.println("============");
        zi.method();
    }
}

super()或者 super(实参) -> 必须要在构造第一行写

2.2 this 的具体使用

java
1.概述:代表的是当前对象 -> 哪个对象调用的this所在的方法,this就代表哪个对象
2.作用:
  a.区分重名的成员变量和局部变量
  b.调用当前对象的成员

3.使用:
  a.调用当前对象的构造:在本类的构造中
    this()调用当前对象的无参构造
    this(实参)调用当前对象的有参构造
  b.调用当前对象的成员变量:在本类中
    this.成员变量名
  c.调用当前对象的方法:在本类中
    this.方法名()
java
public class Person {
    String name = "张三丰";

    public Person(){
        this("张无忌");//调用当前对象的有参构造
        //super();
        System.out.println("Person的无参构造");
    }

    public Person(String name){
        //this();//调用当前对象的无参构造
        System.out.println("Person的有参构造");
    }

    public void eat(String name){
        System.out.println(name);//张翠山
        System.out.println(this.name);
        System.out.println("人要吃饭");
        //this.drink();
    }
    public void drink(){
        System.out.println("人要喝水");
    }
}
java
public class Test01 {
    public static void main(String[] args) {
        Person person = new Person();
        person.eat("张翠山");
    }
}

this()或者 this(实参) 也必须要在构造第一行

所以,this 和 super 就不能同时在构造方法中出现

3.继承的特点

java
1.继承只支持单继承,不能多继承 -> 一个子类只能有一个亲爹
  public class A extends B,C{}  错误
  public class A extends B{} 正确

2.继承支持多层继承
  public class A extends B{}
  public class B extends C{}

3.一个父类可以有多个子类
  public class A extends C{}
  public class B extends C{}

4.问题:如何为父类中 private 的成员变量赋值

4.1.利用 set 赋值

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

    public Employee() {
    }

    public Employee(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 work(){
        System.out.println("员工都要工作");
    }
}
java
public class Teacher extends Employee{
}
java
public class Test01 {
    public static void main(String[] args) {
        Teacher teacher = new Teacher();
        //teacher.name = "涛哥";
        //teacher.age = 16;
        //System.out.println(teacher.name+"..."+teacher.age);
        teacher.setName("涛哥");
        teacher.setAge(16);
        System.out.println(teacher.getName()+"..."+teacher.getAge());
        teacher.work();

    }
}

4.2.利用构造方法赋值

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

    public Employee() {
    }

    public Employee(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 work(){
        System.out.println("员工都要工作");
    }
}
java
public class Manager extends Employee{
    public Manager() {
    }

    public Manager(String name, int age) {
        super(name, age);
    }
}
java
public class Test01 {
    public static void main(String[] args) {
        Teacher teacher = new Teacher();
        //teacher.name = "涛哥";
        //teacher.age = 16;
        //System.out.println(teacher.name+"..."+teacher.age);
        teacher.setName("涛哥");
        teacher.setAge(16);
        System.out.println(teacher.getName()+"..."+teacher.getAge());
        teacher.work();

        System.out.println("==============================");
        Manager manager = new Manager("萌姐",60);
        System.out.println(manager.getName()+"..."+manager.getAge());
    }
}
1742798914678

第三章.抽象

1742802426244

1.抽象的介绍

java
1.抽象类和抽象方法的形成:
   a.将共有的方法抽取到父类之后,在父类中无法做具体实现,此时就可以定义成抽象方法,延伸到子类中做具体的实现
  b.抽象方法所在的类一定是抽象类
2.抽象类的定义 -> abstract
   public abstract class 类名{}
3.抽象方法的定义
  修饰符 abstract 返回值类型 方法名(形参);
4.实现:
   a.定义一个子类,继承抽象父类
   b.重写抽象父类中所有的抽象方法,做具体实现
   c.创建子类对象(抽象父类不能new对象)
   d.调用子类重写的方法
5.继承是为了少写代码,但是现在将父类中的方法整
成抽象的,还必须在子类中重写一遍,那么继承还有
什么意义呢?
   抽象也是一个代码的"设计思想",可用可不用,但是用了比不用强

6.可以将"抽象类"看做是一类事物的标准,只要属于我这个分类,就必须拥有我这个分类的功能,怎么代表拥有 -> 重写
java
1.定义抽象类,类中定义抽象方法
2.定义子类,继承抽象父类
3.重写所有抽象方法 -> alt+回车 -> Implenment methods
4.创建子类对象(抽象类不能new对象),调用重写的方法
java
public abstract class Animal {
    public abstract void eat();
}
java
public class Dog extends Animal{
    @Override
    public void eat() {
        System.out.println("狗吃屎");
    }
}
java
public class Cat extends Animal{
    @Override
    public void eat() {
        System.out.println("猫吃鱼");
    }
}
java
public class Test01 {
    public static void main(String[] args) {
        Dog dog = new Dog();
        dog.eat();

        Cat cat = new Cat();
        cat.eat();
    }
}

2.抽象的注意事项

java
1.抽象类不能直接new对象,只能创建非抽象子类的对象
2.抽象类中,可以有构造方法,是供子类创建对象时,初始化父类中属性使用的
3.抽象类中可以有成员变量,构造,成员方法
4.抽象类中不一定非得有抽象方法,但是有抽象方法的类一定是抽象类
5.抽象类的子类,必须重写父类中的所有抽象方法,否则,编译无法通过.除非该子类也是抽象类
java
public abstract class Employee {
    private String name;
    private int age;

    public Employee() {
    }

    public Employee(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 abstract void work();
}
java
public class Teacher extends Employee{
    public Teacher() {
    }

    public Teacher(String name, int age) {
        super(name, age);
    }

    @Override
    public void work() {
        System.out.println("涛哥在讲课");
    }
}
java
public class Test01 {
    public static void main(String[] args) {
        Teacher t1 = new Teacher("涛哥", 16);
        System.out.println(t1.getName()+"..."+t1.getAge());
    }
}

第四章.综合案例_作业

java
某IT公司有多名员工,按照员工负责的工作不同,进行了部门的划分(研发部、维护部)。
研发部(Developer)根据所需研发的内容不同,又分为 JavaEE工程师 、Android工程师 ;
维护部(Maintainer)根据所需维护的内容不同,又分为 网络维护工程师(Network) 、硬件维护工程师(Hardware) 。

公司的每名员工都有他们自己的员工编号、姓名,并要做他们所负责的工作。

工作内容:
- JavaEE工程师: 员工号为xxx的 xxx员工,正在研发电商网站
- Android工程师:员工号为xxx的 xxx员工,正在研发电商的手机客户端软件
- 网络维护工程师:员工号为xxx的 xxx员工,正在检查网络是否畅通
- 硬件维护工程师:员工号为xxx的 xxx员工,正在修复电脑主板

请根据描述,完成员工体系中所有类的定义,并指定类之间的继承关系。进行XX工程师类的对象创建,完成工作方法的调用。

方式 1:利用 set 赋值

java
java
java
java

方式 2:利用构造赋值

java
java
java
java