Skip to content

day10.面向对象

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

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

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

请根据描述,完成员工体系中所有类的定义,并指定类之间的继承关系。进行XX工程师类的对象创建,完成工作方法的调用。
java
public abstract class Employee {
    private int id;
    private String name;

    public Employee() {
    }

    public Employee(int id, String name) {
        this.id = id;
        this.name = name;
    }

    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();
}

public abstract class Developer extends Employee{
    public Developer() {
    }

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

public class JavaEE extends Developer{
    public JavaEE() {
    }

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

    @Override
    public void work() {
        System.out.println("员工号为:"+this.getId()+"的"+this.getName()+"正在研发电商网站");
    }
}

public class Test01 {
    public static void main(String[] args) {
        JavaEE javaEE = new JavaEE(1, "涛哥");
        javaEE.work();
    }
}
1742863959490

1.封装:将细节隐藏起来(不让外界直接使用),对外提供一套公共的接口(让外界通过这个公共接口间接调用隐藏起来的细节)

​ a.有代表性的关键字:private -> 私有化

​ b.get/set 方法 -> 提供的公共接口

​ c.构造:

​ 无参构造:new 对象

​ 有参构造:new 对象的同时,为属性赋值

2.继承:将子类中共有的内容抽取到父类中,子类直接继承父类,就可以直接使用父类中非私有成员

a.关键字:extends

b.成员变量:看等号左边是谁

​ 成员方法:看 new 的是谁

3.抽象:定义抽象类,里面定义抽象方法

a.定义子类,继承抽象父类

b.重写所有抽象方法

c.创建子类对象,调用重写的方法

java
今日重点:
  1.会定义接口,实现接口
  2.会在接口中定义抽象方法
  3.知道多态的前提
  4.知道多态前提下成员访问特点
  5.知道多态的好处和弊端
  6.知道如何向下转型,调用子类特有功能
  7.知道如何判断类型 -> instanceof

第一章.接口

1.接口的介绍

1742865459229

2.接口的定义以及使用

java
1.接口:是一种规则,一种标准
2.既然是一种标准,里面的成员就非常单一
3.jdk8之前:
  a.抽象方法:不带abstract,默认也有
  b.成员变量:必须是带public static final的,不写也有

 4. jdk8开始:多了两个
   a.默认方法:带default关键字的
   b.静态方法:带static的方法

5.jdk9开始:多了一个
   a.私有方法:带private

6.接口的定义:interface
   public interface 接口名{}

7.实现接口: implements
   实现类 implements 接口名{}
java
1.创建接口
2.创建实现类,实现此接口
3.在实现类中重写接口中所有的抽象方法
4.创建实现类对象(接口不能new对象),调用重写的方法
java
public interface USB {
    public abstract void open();
    public abstract void close();
}
java
public class Mouse implements USB{
    @Override
    public void open() {
        System.out.println("鼠标打开");
    }

    @Override
    public void close() {
        System.out.println("鼠标关闭");
    }
}
java
public class Test01 {
    public static void main(String[] args) {
        Mouse mouse = new Mouse();
        mouse.open();
        mouse.close();
    }
}

3.接口中的成员

3.1 抽象方法

java
1.定义格式:
  public abstract 返回值类型 方法名(形参);
2.特点:
  不写abstract关键字默认也有
3.实现:
  在实现类中重写
java
public interface USB {
    public abstract void open();
    void close();
}
java
public class Mouse implements USB {
    @Override
    public void open() {
        System.out.println("鼠标打开");
    }

    @Override
    public void close() {
        System.out.println("鼠标关闭");
    }
}
java
public class Test01 {
    public static void main(String[] args) {
        Mouse mouse = new Mouse();
        mouse.open();
        mouse.close();
    }
}

3.2 默认方法

java
1.定义格式:
  public default 返回值类型 方法名(形参){
      方法体
      return 结果
  }

2.使用:
  a.可重写,可不重写
  b.创建实现类对象,调用默认方法
java
public interface USB {
    //默认方法
    public default void methodDef(){
        System.out.println("我是接口中的默认方法");
    }
}
java
public class Mouse implements USB{
    @Override
    public void methodDef(){
        System.out.println("我是重写的接口中的默认方法");
    }
}
java
public class Test01 {
    public static void main(String[] args) {
        Mouse mouse = new Mouse();
        mouse.methodDef();
    }
}

3.3 静态方法

java
1.定义格式:
  修饰符  static 返回值类型 方法名(形参){
      方法体
      return 结果
  }

2.实现:
  接口名直接调用
java
public interface USB {
    //默认方法
    public default void methodDef(){
        System.out.println("我是接口中的默认方法");
    }

    //静态方法
    public static void methodStatic(){
        System.out.println("我是接口中的静态方法");
    }
}
java
public class Test01 {
    public static void main(String[] args) {
        Mouse mouse = new Mouse();
        mouse.methodDef();

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

        USB.methodStatic();
    }
}

默认方法和静态方法:如果我们将来需要临时加一个功能,但是这个功能用不了几行代码就能完成,我们就没必要先定义抽象方法,然后再在实现类中重写了,此时我们就可以直接在接口中定义默认方法或者静态方法

3.4 成员变量

java
1.格式:public static final 数据类型 变量名 =
2.特点:不写 public static final 默认也有
3.没学的关键字: final -> 代表最终的 -> 被final修饰的变量不能二次赋值,我们认为是常量
4.调用:接口名直接调用
5.注意:
  a.被static final修饰的变量需要手动赋值
  b.习惯上将static final修饰的变量名大写
java
public interface USB {
    //成员变量
    public static final int NUM = 10;
    int NUM1 = 100;
}
java
public class Test01 {
    public static void main(String[] args) {
        System.out.println(USB.NUM);
        System.out.println(USB.NUM1);
    }
}

3.5.私有方法

java
1.格式:
  private 返回值类型 方法名(形参){
      方法体;
      return 结果;
  }
java
public interface USB {
    private void methodPrivate(){
        System.out.println("接口中的私有方法");
    }

    public default void methodDef(){
        methodPrivate();
    }
}
java
public class Mouse implements USB{
}
java
public class Test01 {
    public static void main(String[] args) {
        Mouse mouse = new Mouse();
        mouse.methodDef();
    }
}

特殊语法:

接口名.super.方法名()

public class 实现类 implements 接口 A,接口 B{

​ public void method(){

​ 接口名.super.方法名()

​ }

}

public interface 接口 A{

​ default void method(){

​ }

}

public interface 接口 B{

​ default void method(){

​ }

}

4.接口的特点

java
1.接口可以多实现:一个类可以实现一个或者多个接口
  public class InterfaceImpl implements InterfaceA,InterfaceB{}
2.接口可以多继承:一个接口可以继承一个或者多个接口
  public interface InterfaceC extends InterfaceA,InterfaceB{}
3.一个类可以继承一个父类的同时实现一个或者多个接口
  public class Zi extends Fu implements InterfaceA,InterfaceB{}

当一个类实现多个接口时,如果接口中的抽象方法有重名且参数一样的,只重写一次

java
public interface InterfaceA {
    public abstract void method();
}
java
public interface InterfaceB {
    public abstract void method();
}
java
public class InterfaceImpl implements InterfaceA,InterfaceB{
    @Override
    public void method() {
        System.out.println("我是重写的method方法");
    }
}

当一个类实现多个接口时,如果默认方法有重名的,参数一样,默认方法必须要重写一次

java
public interface InterfaceA {
    public abstract void method();

    public default void methodDef() {
    	System.out.println("InterfaceA.methodDef()");
    }
}
java
public interface InterfaceB {
    public abstract void method();
    public default void methodDef() {
        System.out.println("InterfaceB.methodDef()");
    }
}
java
public class InterfaceImpl implements InterfaceA,InterfaceB{
    @Override
    public void method() {
        System.out.println("我是重写的method方法");
    }

    @Override
    public void methodDef() {
        System.out.println("重写的methodDef方法");
    }
}

5.接口和抽象类的区别

java
相同点:
  a.都位于继承的顶端,用于被其他类实现或者继承
  b.都不能new
  c.都包含抽象方法,其子类都必须重写这些抽象方法

不同点:
  a.抽象类:一般作为父类使用,可以有成员变量,构造,成员方法,抽象方法等
  b.接口:成员单一,一般抽取接口,抽取的都是方法,是功能的大集合
  c.类不能多继承,接口可以
1742872871359

第二章.多态

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

1.多态的介绍

java
1.怎么学多态:
  a.前提  b.如何new对象  c.多态好处

2.前提:
  a.必须有子父类继承关系或者接口实现关系
  b.必须有方法的重写(没有方法的重写,多态没有任何意义)
  c.new对象 -> 父类引用指向子类对象 -> Fu fu = new Zi()

2.多态的基本使用

java
1.定义一个父类或者接口
2.定义一个子类或者实现类去继承或者实现父类或接口
3.重写父类或者接口中的抽象方法
4.创建对象,调用重写的方法
java
public class Animal {
    public void eat(){
        System.out.println("动物要吃饭");
    }
}
java
public class Dog extends Animal{
    @Override
    public void eat() {
        System.out.println("狗啃骨头");
    }

    /**
     * 特有功能
     */
    public void lookHome(){
        System.out.println("狗看家");
    }
}
java
public class Test01 {
    public static void main(String[] args) {

        //原始形式
        Dog dog = new Dog();
        dog.eat();
        dog.lookHome();

        System.out.println("===================");
        //多态形式
        Animal animal = new Dog();
        animal.eat();
        //animal.lookHome();多态前提下,不能直接调用子类特有方法

    }
}

3.多态的条件下成员的访问特点

3.1 成员变量

java
看等号左边是谁,先调用谁中的成员变量
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) {
        //多态形式
        Fu fu = new Zi();
        System.out.println(fu.num);
    }
}

3.2 成员方法

java
看new的是谁,先调用谁中的方法,子类没有,找父类
java
public class Fu {
    int num = 100;
    public void method(){
        System.out.println("我是父类中的method方法");
    }
}
java
public class Zi extends Fu{
    int num = 10;
    @Override
    public void method(){
        System.out.println("我是子类中的method方法");
    }
}
java
public class Test01 {
    public static void main(String[] args) {
        //多态形式
        Fu fu = new Zi();
        System.out.println(fu.num);
        fu.method();
    }
}

4.多态的好处(为什么学多态)

java
1.问题:
  我们按照原始方式创建对象,既可以调用继承过来的,还能调用重写的,还能调用特有的;但是我们用多态形式new对象,不能调用子类特有功能,只能调用重写的方法,那么为啥还要用多态呢?


2.原始方式:
  a.好处:既可以调用继承过来的,还能调用重写的,还能调用特有的
  b.坏处:扩展性差

3.多态方式:
  a.好处:扩展性强
  b.坏处:不能直接调用子类特有功能
java
public class Animal {
    public void eat(){
        System.out.println("动物要干饭");
    }
}
java
public class Dog extends Animal{
    @Override
    public void eat() {
        System.out.println("狗吃屎");
    }

    //特有方法
    public void lookHome(){
        System.out.println("狗会看家");
    }
}
java
public class Cat extends Animal{
    @Override
    public void eat() {
        System.out.println("猫吃鱼");
    }

    //特有方法
    public void catchMouse(){
        System.out.println("抓老鼠");
    }
}
java
public class Test01 {
    public static void main(String[] args) {
        //原始方式创建对象
        Dog dog = new Dog();
        dog.eat();
        dog.lookHome();

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

        //多态方式创建对象
        Animal animal = new Dog();
        animal.eat();
        //animal.lookHome();不能直接调用子类特有功能
    }
}
java
public class Test02 {
    public static void main(String[] args) {
        Dog dog = new Dog();
        method(dog);

        Cat cat = new Cat();
        method(cat);

        /*Pig pig = new Pig();
        method(pig);

        Duck duck = new Duck();
        method(duck);*/
    }

    public static void method(Dog dog){
        dog.eat();
    }

    public static void method(Cat cat){
        cat.eat();
    }

    /*public static void method(Pig pig){
        pig.eat();
    }*/
}
java
public class Test03 {
    public static void main(String[] args) {
       /* Animal animal = new Dog();
        animal.eat();

        *//*
           好比是:
             double b = 10;
             b = 2.5;
         *//*
        animal = new Cat();
        animal.eat();*/

        Dog dog = new Dog();
        method(dog);

        Cat cat = new Cat();
        method(cat);
    }

    /**
     * 形参位置设置的是父类类型
     * 那么就可以接收任意它的子类对象
     * 接收哪个子类对象,就会指向哪个子类对象
     * 就会调用哪个子类对象重写的方法
     * 扩展性好强
     * @param animal
     */

    public static void method(Animal animal){//Animal animal = dog  Animal animal = cat
        animal.eat();
    }

}

5.多态中的转型

5.1 向上转型

java
 默认的: 父类引用指向子类对象

5.2 向下转型

java
1.将父类类型转成子类类型 -> 强转
2.向下转型的作用:
  调用子类特有方法
3.使用:
  Fu fu = new Zi();
  Zi zi = (Zi)fu;
java
public class Animal {
    public void eat(){
        System.out.println("动物要干饭");
    }
}
java
public class Dog extends Animal {
    @Override
    public void eat() {
        System.out.println("狗吃屎");
    }

    //特有方法
    public void lookHome(){
        System.out.println("狗会看家");
    }
}
java
public class Test01 {
    public static void main(String[] args) {
        //向上转型
        Animal animal = new Dog();
        animal.eat();
        //向下转型
        Dog dog = (Dog) animal;
        dog.lookHome();
    }
}

6.转型可能会出现的问题

java
1.类型转换异常:
  ClassCastException
2.原因:
  强转的时候等号左右两边类型不一致
3.判断: instanceof -> 判断类型
  a.格式1: 对象名 instanceof 类型 -> 判断instanceof前面的对象是否属于关键字后面的类型

  b.格式2: 对象名 instanceof 类型 对象名 -> 会自动强转
java
public class Animal {
    public void eat(){
        System.out.println("动物要干饭");
    }
}
java
public class Cat extends Animal {
    @Override
    public void eat() {
        System.out.println("猫吃鱼");
    }

    //特有方法
    public void catchMouse(){
        System.out.println("抓老鼠");
    }
}
java
public class Dog extends Animal {
    @Override
    public void eat() {
        System.out.println("狗吃屎");
    }

    //特有方法
    public void lookHome(){
        System.out.println("狗会看家");
    }
}
java
public class Test01 {
    public static void main(String[] args) {
        Dog dog = new Dog();
        method(dog);
        Cat cat = new Cat();
        method(cat);
    }

    public static void method(Animal animal){//Animal animal = dog  Animal animal = cat
        //animal.eat();
        /*
           向下转型
           调用method方法,传递Cat对象,animal实际上接收的是Cat对象
           将接收到Cat对象的animal强转成Dog类型
           实际上类型是不一样的

           格式1: 对象名 instanceof 类型 -> 判断instanceof前面的对象是否属于关键字后面的类型
         */
       /* if (animal instanceof Dog){
            Dog dog = (Dog) animal;
            dog.lookHome();
        }

        if (animal instanceof Cat){
            Cat cat = (Cat) animal;
            cat.catchMouse();
        }*/

        //格式2: 对象名 instanceof 类型 对象名 -> 会自动强转
        if (animal instanceof Dog dog){
            dog.lookHome();
        }

        if (animal instanceof Cat cat){
            cat.catchMouse();
        }

    }
}

7.综合练习

java
定义笔记本类,具备开机,关机和使用USB设备的功能。具体是什么USB设备,笔记本并不关心,只要符合USB规格的设备都可以。鼠标和键盘要想能在电脑上使用,那么鼠标和键盘也必须遵守USB规范,不然鼠标和键盘生产出来无法使用;
进行描述笔记本类,实现笔记本使用USB鼠标、USB键盘

- USB接口,包含开启功能、关闭功能
- 笔记本类,包含运行功能、关机功能、使用USB设备功能
- 鼠标类,要符合USB接口
- 键盘类,要符合USB接口
java
public interface USB {
   void open();
   void close();
}
java
public class Mouse implements USB{
    @Override
    public void open() {
        System.out.println("鼠标开启");
    }

    @Override
    public void close() {
        System.out.println("鼠标关闭");
    }

    //特有方法
    public void click(){
        System.out.println("鼠标点击");
    }
}
java
public class KeyBoard implements USB{
    @Override
    public void open() {
        System.out.println("键盘开启");
    }

    @Override
    public void close() {
        System.out.println("键盘关闭");
    }

    //特有方法
    public void input(){
        System.out.println("键盘输入");
    }
}
java
public class Computer {
    public void start(){
        System.out.println("开机");
    }

    /**
     * 传递mouse -> USB usb = mouse -> 多态
     * 传递keyBoard -> USB usb = keyBoard -> 多态
     * @param usb
     */
    public void useUSB(USB usb){
        usb.open();
        usb.close();
        if (usb instanceof Mouse mouse){
            mouse.click();
        }

        if (usb instanceof KeyBoard keyBoard){
            keyBoard.input();
        }

    }

    public void stop(){
        System.out.println("关机");
    }
}
java
public class Test01 {
    public static void main(String[] args) {
        Computer computer = new Computer();
        Mouse mouse = new Mouse();
        KeyBoard keyBoard = new KeyBoard();
        computer.start();
        computer.useUSB(mouse);
        computer.useUSB(keyBoard);
        computer.stop();
    }
}
1742888917767

第三章.权限修饰符

1 概述

在 Java 中提供了四种访问权限,使用不同的访问权限修饰符修饰时,被修饰的内容会有不同的访问权限,

  • public:公共的,最高权限,被 public 修饰的成员,在哪里都能访问
  • protected:受保护的
  • default::默认的 注意 不写权限修饰符就是默认权限,不能直接把 default 写出来
  • private:私有的,只能在自己的类中直接访问

2 不同权限的访问能力

publicprotecteddefault(空的)private
同类yesyesyesyes
同包不同类yesyesyesno
不同包子父类yesyesnono
不同包非子父类yesnonono

public 具有最大权限,private 有最小权限

编写代码时,如果没有特殊的考虑,建议这样使用权限:

java
属性用private -> 封装思想
构造用public -> 便于new对象
方法用public -> 便于调用

第四章.final 关键字

java
1.概述:代表的是最终的
2.使用:
  修饰类
  修饰方法
  修饰对象
  修饰局部变量
  修饰成员变量

1.final 修饰类

java
1.格式:
  public final class 类名{}
2.特点:
  不能被继承
java
public final class Animal {

}
java
public class Dog /*extends Animal*/{
}

2.final 修饰方法

java
1.格式:
  修饰符 final 返回值类型 方法名(形参){
      方法体
      return 结果
  }

2.特点:
  a.不能被重写
  b.不能和abstract一起使用
java
public abstract class Animal {
    public final void eat(){

    }

    //public final abstract void drink();
}
java
public class Dog extends Animal{
   /* @Override
    public void eat() {
        System.out.println("狗吃骨头");
    }*/
}

3.final 修饰局部变量

java
1.格式:
  final 数据类型 变量名 =
2.特点:
  不能被二次赋值
java
public class Test01 {
    public static void main(String[] args) {
        final int i = 10;
        //i = 20;

    }
}

4.final 修饰对象

java
1.格式:
  final 类名 对象名 = new 类名()
2.特点:
  地址值不能改变,但是属性值可以改变
java
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;
    }
}
java
public class Test02 {
    public static void main(String[] args) {
        final Person p1 = new Person("jack", 20);
        System.out.println(p1);//地址值
        //p1 = new Person("rose", 18);
        //System.out.println(p1);//地址值
        p1.setName("rose");
        System.out.println(p1.getName());
    }
}

5.final 修饰成员变量

java
1.格式:
  final 数据类型 变量名 =
2.特点:
  a.被final修饰的成员变量不能被二次赋值
  b.被final修饰的成员变量手动赋值
java
public class Student {
    final String name = "张三";

    public Student() {
    }
/*    public Student(String name) {
        this.name = name;
    }

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

    public String getName() {
        return name;
    }
}