Java学习笔记——day05面向对象(续1)

面向对象

  • 多态
  • 抽象类
  • 接口

1. 多态

多态:同样的引用,调用方法,却做了不同的事;

1.1 概述

在设计一个方法时,通常希望该方法具备特定的通用性。比如要实现某一类教师教授的课业答方法时,由于每类教师教授的课业都是不同的,因此可以在方法中接收一个教授课业类型的参数,当传入Java讲师类对象时就会教授Java,传入Python讲师类对象时就会教授python。

在同一方法中,由于参数类型不同而导致执行效果不同的现象就是多态。

1.2 多态前提

  • 要有继承关系:

      注:多态中必须存在有继承关系的子类和父类;
    
  • 要有方法重写:

      注:子类对父类中某些方法进行重新定义,在调用这些方法时就会调用子类的方法;
    
  • 向上转型:

      注:在多态中需要将子类的引用赋给父类对象,只有这样才能够具备技能调用父类的方法和子类的方法;
    

1.3 实例演示

  • 调用格式

    Father f = new Son();//向上转型

  • 案例

    public class Test1 {
        public static void main(String[] args) {
            Teacher t1 = new JavaTeacher();
            //实现了父类类型变量引用不同的子类对象    
            Teacher t2 = new PythonTeacher();
            //实现了父类类型变量引用不同的子类对象    
    
            t1.teach();
            t2.teach();
            //调用teach()方法时,将父类引用的两个不同子类对象分
            //别传入,就打印除了“教授Java”“教授Python”
        }
    }
    
    class Teacher{
        public void teach(){
            System.out.println("教书");
        }
    }
    //定义JavaTeacher类继承Teacher
    class JavaTeacher extends Teacher{
        //实现teach()方法重写
        @Override
        public void teach() {
            System.out.println("教授Java");
        }
    }
    //定义PythonTeacher类继承Teacher
    class PythonTeacher extends Teacher{
        //实现teach()方法重写
        @Override
        public void teach() {
            System.out.println("教授Python");
        }
    }
    

    由此可见,多态提高了代码的维护性(继承保证),提高了代码的扩展性(多态保证);

1.4 多态中访问成员变量的特点

  • 成员变量

    编译看左边,运行看左边;

  • 构造方法

    创建子类对象的时候,会访问父类的构造方法,对父类的数据进行初始化;

  • 成员方法

    编译看左边,运行看右边;

  • 静态方法

    编译看左边,运行看右边;

    (静态和类相关,算不上重写,所以,访问还是看左边)

1.5 多态的弊端

  • 弊端引起的问题:不能使用子类特有的功能;
  • 解决方案:把父类的引用强制转换为子类的引用;
  • 实例:
public class Test1 {
    public static void main(String[] args) {
        Teacher t1 = new JavaTeacher();
        Teacher t2 = new PythonTeacher();
        t1.teach();
        //t1.playGame();  //会报错,显示无法找到
        ((JavaTeacher) t1).playGame();  //把Teacher(父类)的引用强制转换为JavaTeacher(子类)的引用,这就是所谓的向下转型
    }
}
class Teacher{
    public void teach(){
        System.out.println("教书");
    }
}

class JavaTeacher extends Teacher {
    @Override
    public void teach() {
        System.out.println("教授Java");
    }

    public void playGame() {
        System.out.println("荣耀王者");
    }
}
class PythonTeacher extends Teacher{
    @Override
    public void teach() {
        System.out.println("教授Python");
    }
}

2. 抽象类

2.1 概述

2.1.1 抽象类
  • 定义:用abstract修饰的类就是抽象类;
  • 格式:
public abstract class 类名{
}
2.1.2 抽象方法
  • 定义:没有方法体的方法,并且使用abstract关键字修饰的方法;
  • 格式:
权限修饰符 abstract 返回值类型 方法名(形参);
eg: public abstract void teach();
2.1.3 实例演示
public class Test3 {
    public static void main(String[] args) {

        Employee employee = new Manager();
        //用set方法加入经理信息
        employee.setName("张经理");
        employee.setIdNum(001);
        employee.setSalary(5000);
        ((Manager) employee).setBounds(3000);
        //用get方法获取经理信息
        System.out.println(employee.getName());
        System.out.println(employee.getIdNum());
        System.out.println(employee.getSalary());
        System.out.println(employee.getSalary());
        ((Manager) employee).work();
    }
}
//员工类
abstract class Employee{
    private String name;
    private int idNum;
    private double salary;
    //name
    public void name(){

    };
    //工号
    public void idNum(){

    };
    //工资
    public void salary(){

    };

    public Employee() {
    }
    //get set 方法
    public String getName() {
        return name;
    }

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

    public int getIdNum() {
        return idNum;
    }

    public void setIdNum(int idNum) {
        this.idNum = idNum;
    }

    public double getSalary() {
        return salary;
    }

    public void setSalary(double salary) {
        this.salary = salary;
    }

    //抽象类方法
    abstract void work();
}
//经理类
class Manager extends Employee{

   private double  bounds;

    public double getBounds() {
        return bounds;
    }

    public void setBounds(double bounds) {
        this.bounds = bounds;
    }

    @Override
    void work() {
        System.out.println("管理工作");
    }
}
2.1.4 特点
  • 抽象类和抽象方法必须用abstract关键字修饰;

  • 抽象类不一定有抽象方法,有抽象方法的类一定是抽象类或接口;

      注:一个抽象类如果没有抽象方法,是可以定义为抽象类的,这么做是为了不让其他类创建本类对象,抽象方法是交给子类完成的。
    
  • 抽象类不能实例化,那么抽象类如何实例化呢?

      注:按照多态的方式,由具体的子类实例化。
    
  • 抽象的子类

      注:要么是抽象类,要么是重写抽象类中的所有抽象方法
    
  • 抽象类中可以有构造方法,抽象类不能进行实例化,那么要构造方法有什么作用呢?

      注:用于子类访问父类数据时的初始化;
    
2.1.5 抽象类的成员特点
  • 成员变量:变量或常量;
  • 构造方法:有,用于子类访问父类数据的初始化;
  • 成员方法:
    • 抽象方法:强制要求子类做的事;
    • 非抽象方法:子类继承的事情,提高代码的复用性;
2.1.6 与abstract不能共存的关键字
  • abstract和static

      注: 1.被abstract修饰的方法没有方法体;
      	   2.被static修饰的方法可以用类名,调用方法,但是类名调用抽象方法是没有意义的; 
    
  • abstract和final

      注:1. 被abstract修饰的方法强制子类重写;
      	  2. 被final修饰的方法不让子类重写;
    
  • abstract和private

      注:1. 被abstract修饰是为了让子类看到并强制重写;
      	  2. 被private修饰不让子类访问;
    

3. 接口

3.1 概述

3.1.1 问题

Java中只支持单继承,但是有些定义的功能想让一个子类都可以继承实现,就无法做到;

3.1.2 解决办法

Java提供了接口的概念,我们可以用一个子类去实现多个接口。去解决单继承问题;

3.2 特点

  • 接口用关键字iinterface表示

    interface 接口名{
    }
    
  • 类实现接口用implements表示

    class 类名 implements 接口名{
    }
    
  • 接口不能实例化,需要按照多态的 方式来实例化;

  • 接口的子类

    • 抽象类:基本无意义;
    • 具体类:需要重写接口中的所有抽象方法;
  • 成员特点

    • 成员变量: 只能是常量,并且是静态的,

      ​ 默认修饰符 public static final

    • 构造方法:无;

    • 成员方法:只能是抽象的方法;

      ​ 默认修饰符: public abstract

3.3 实例

package day2;
/*
	动物类:姓名,年龄,吃饭,睡觉。
	动物培训接口:跳高
	猫继承动物类
	部分猫继承猫类并实现跳高接口
	通过抽象类测试基本功能。
	通过接口测试扩展功能。
*/
public class Test5 {
    public static void main(String[] args) {

        Animal cat_ju = new 橘猫();
        cat_ju.setName("橘猫");
        cat_ju.setAge(10);
        System.out.print(cat_ju.getName()+"今年"+cat_ju.getAge()+"岁了,");
        cat_ju.eat();
        cat_ju.sleep();
        ((橘猫) cat_ju).catchMouse();

        Animal cat_jia = new 加菲猫();
        cat_jia.setName("加菲");
        cat_jia.setAge(8);
        System.out.print(cat_jia.getName()+"今年"+cat_jia.getAge()+"岁了,");
        cat_jia.eat();
        cat_jia.sleep();
        ((加菲猫) cat_jia).Jump();


    }
}
//动物类:姓名,年龄,吃饭,睡觉。
abstract class Animal{

    private String name;
    private int age;
    public abstract void eat();
    public abstract void sleep();

    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;
    }
}
//动物培训接口:跳高
interface JumpInterface{
    public void Jump();
}
//猫继承动物类
class Cat extends Animal{
    @Override
    public void eat() {
        System.out.println("猫吃鱼");
    }

    @Override
    public void sleep() {
        System.out.println("猫睡沙发");
    }
}

class 橘猫 extends Cat{
    @Override
    public void eat() {
        System.out.print("喜欢吃大蒜,");
    }

    @Override
    public void sleep() {
        System.out.print("睡在桌子底下,");
    }

    public void catchMouse(){
        System.out.println("只抓白色的老鼠");
    }
}

class 加菲猫 extends Animal implements JumpInterface{

    @Override
    public void eat() {
        System.out.print("喜欢吃千层面,");
    }

    @Override
    public void sleep() {
        System.out.print("睡在狗子的身上,");
    }

    @Override
    public void Jump() {
        System.out.println("跳高记录1.5m");
    }
}

3.4 类与类,接口与接口,类与接口

  • 类与类

    继承关系,只能单继承,可以多层继承;

  • 类与接口

    实现关系,可以单实现,也可以多实现;

    并且还可以在继承一个类的同时实现多个接口;

  • 接口与接口

    继承关系,可以单继承,也可以多继承;

3.5 抽象类与接口的区别

参考链接:https://blog.csdn.net/weixin_44547508/article/details/90181964

抽象类接口
默认的实现方法它可以有默认的实现方法接口完全是抽象的,它根本不存在方法的实现
实现子类使用extends关键字来继承抽象类,若子类非抽象类,则需提供抽象类中所有声明的抽象方法的实现类使用关键字implements来实现接口。它需要提供接口中所有声明的方法来实现
构造器抽象类可以有构造器接口不能有构造器
与正常Java类的区别除了不能实例化抽象类之外,没有区别接口是完全不同的类型
访问修饰符抽象方法可以有public、protected和default这些修饰符接口默认修饰符是public,不可以使用其它的
main方法抽象方法可以有main方法并且可以运行它接口没有main方法
多继承抽象类可以继承一个类和实现多个接口接口可以继承一个或多个其它接口
添加新方法往抽象类中添加新方法,可以提供默认实现,不需要改变现在的代码往接口中添加新方法,需要改变实现接口的类
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值