抽象类、接口、内部类

1 篇文章 0 订阅
1 篇文章 0 订阅

抽象类、接口、内部类

1:抽象类

  • 理解抽象的设计思想

在这里插入图片描述

  • abstract关键字的使用
/**
 * 举例1:
 * abstract class Account{
 *     double balance;
 *
 *     //存钱、取钱的方法
 * }
 *
 * class SavingAccount extends Account{
 *
 * }
 * class CheckAccount extends Account{
 *
 * }
 *
 * class Customer{
 *     Account acct;
 *     public void setAccount(Account acct){ //Account acct = new SavingAccount();
 *         this.acct = acct;
 *     }
 *
 * }
 *
 * 1. abstract:抽象的
 * 2. 可以用来修饰:类、方法
 *
 * 3. abstract 来修饰类:抽象类
 *      > 此类就不可以实例化(不能创建对象)  ---> 凡是类,内部都有构造器。
 *              -->此时抽象类提供构造器的意义:为了子类对象实例化进行对抽象父类中构造器的调用
 *      > 在开发中,针对于抽象类,我们一定会提供其子类。在实现过程中,创建子类的对象。
 *
 * 4. abstract 来修饰方法:抽象方法
 *      > 特点:抽象方法,没有方法体结构。
 *      > 抽象类中可以没有抽象方法;但是,抽象方法所在的类,一定是抽象类。
 *      > 如果抽象类的子类重写了父类中的所有的抽象方法,则此子类可以实例化。
 *        如果抽象类的子类没有重写父类中所有的抽象方法,则此子类也必须声明为abstract的。
 *
 *
 *
 * @author Begonia_sea
 * @create 2020-07-10 
 */
  • 代码举例
public class AbstractTest {

    public static void main(String[] args) {
//        Person p1 = new Person();
//        p1.eat();

        Student s1 = new Student();
        s1.eat();

//        Worker w1 = new Worker();
//        w1.eat();

        //提供抽象类的匿名子类的对象
        Person p2 = new Person(){

            @Override
            public void eat() {
                System.out.println("人:吃饭");
            }

            @Override
            public void walk() {
                System.out.println("人:走路");
            }

            @Override
            public void breath() {
                System.out.println("人:呼吸");
            }
        };
        p2.eat();

        //创建了BB的匿名子类的对象
        BB b = new BB(){

        };
    }
}

abstract class BB{

}

abstract class Creature{

    public abstract void breath();
}

abstract class Person extends Creature{
    String name;
    int age;

    public Person(){

    }

    public Person(String name,int age){
        this.name = name;
        this.age = age;
    }
    //抽象方法
    public abstract void eat();

    //抽象方法
    public abstract void walk();
}

class Student extends Person{
    String major;

    public Student(){}
    public Student(String name ,int age ,String major){
        super(name, age);
        this.major = major;
    }

    public void eat(){
        System.out.println("学生:多吃有营养的食物");
    }
    public void walk(){
        System.out.println("学生:背着书包上学");
    }

    @Override
    public void breath() {
        System.out.println("学生应该呼吸新鲜的空气");
    }
}

abstract class Worker extends Person{
    String skill;

//    public void eat(){
//        System.out.println("工人:在工厂吃盒饭");
//    }
//    public void walk(){
//        System.out.println("工人:在车间行走");
//    }
}
  • 举例

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bjH1GjMV-1594390601955)(assets/1594370898800.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-43wQmoCm-1594390601957)(assets/1594370912376.png)]

  • abstract的补充说明
/**
 *  不能用abstract修饰变量、代码块、构造器;
 *
 *  不能用abstract修饰私有方法、静态方法、final的方法、final的类。
 *
 * @author Begonia_sea
 * @create 2020-07-10 
 */
public abstract class AbstractTest1 {

//    private abstract void method();
//
//    public static abstract void method1();

}

class A extends AbstractTest1{

}

  • 练习1
public abstract class GeometricObject {
    protected  String color;//颜色
    protected  double weight;//权重

    public GeometricObject(String color, double weight) {
        this.color = color;
        this.weight = weight;
    }

    public String getColor() {
        return color;
    }

    public void setColor(String color) {
        this.color = color;
    }

    public double getWeight() {
        return weight;
    }

    public void setWeight(double weight) {
        this.weight = weight;
    }

    //返回几何图形的面积
    public abstract double findArea();
}
  • 练习2


/**
 * @author  Begonia_sea
 * @create 2020-07-10 
 */
public abstract class Employee {//员工类
    private String name;//姓名
    private int id;//编号
    private double salary;//薪水

    public Employee(String name, int id, double salary) {//构造方法
        this.name = name;
        this.id = id;
        this.salary = salary;
    }

    public abstract void work();//工作方法

    public String getName() {
        return name;
    }

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

    public int getId() {
        return id;
    }

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

    public double getSalary() {
        return salary;
    }

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

    @Override
    public String toString() {
        return
                "name='" + name + '\'' +
                        ", id=" + id +
                        ", salary=" + salary;
    }
}




/**
 * @author shkstart
 * @create 2020-07-10 14:35
 */
public class CommonEmployee extends Employee{//普通员工类

    public CommonEmployee(String name, int id, double salary) {//构造方法
        super(name, id, salary);//调用父类的构造方法
    }

    @Override
    public void work() {//工作方法
        System.out.println("在工地搬砖");
    }

    @Override
    public String toString() {
        return "CommonEmployee{ " + super.toString() +"}";
    }
}



/**
 * @author  Begonia_sea
 * @create 2020-07-10 
 */
public class Manager extends Employee {

    private double bonus;//薪水
    public Manager(String name, int id, double salary) {//构造方法
        super(name, id, salary);//调用父类的构造方法
    }

    @Override
    public void work() {//工作方法
        System.out.println("在办公室工作");
    }

    public double getBonus() {
        return bonus;
    }

    public void setBonus(double bonus) {
        this.bonus = bonus;
    }

    @Override
    public String toString() {
        return "Manager{" +
                super.toString() +
                ",bonus=" + bonus +
                "} ";
    }
}

package com.atguigu.exer1;

/**
 * @author shkstart
 * @create 2020-07-10 14:35
 */
public class EmployeeTest {

    public static void main(String[] args) {
        Manager manager = new Manager("马爷", 1001, 5000);
        manager.setBonus(10000);
        System.out.println(manager);
        manager.work();


        CommonEmployee commonEmployee = new CommonEmployee("杨展", 102, 500);
        System.out.println(commonEmployee);
        commonEmployee.work();

    }
}

  • 练习3


/**
 * 编写工资系统,实现不同类型员工(多态)的按月发放工资。如果当月出现某个Employee对象的
 * 生日,则将该雇员的工资增加100元。
 *
 * 实验说明:
 * (1)定义一个Employee类,该类包含:
 * private成员变量name,number,birthday,其中birthday 为MyDate类的对象;
 * abstract方法earnings();
 * toString()方法输出对象的name,number和birthday。
 *
 * @author  Begonia_sea
 * @create 2020-07-10 
 */
public abstract class Employee {
    private String name;
    private int number;
    private MyDate birthday;

    public Employee(String name, int number, MyDate birthday) {
        this.name = name;
        this.number = number;
        this.birthday = birthday;
    }

    public Employee() {
    }

    public String getName() {
        return name;
    }

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

    public int getNumber() {
        return number;
    }

    public void setNumber(int number) {
        this.number = number;
    }

    public MyDate getBirthday() {
        return birthday;
    }

    public void setBirthday(MyDate birthday) {
        this.birthday = birthday;
    }

    //abstract方法earnings();
    public abstract double earnings();

    @Override
    public String toString() {
        return "name='" + name + '\'' +
                ", number=" + number +
                ", birthday=" + birthday.toDateString();
    }
}







/**
 * (2)MyDate类包含:
 * private成员变量year,month,day ;
 * toDateString()方法返回日期对应的字符串:xxxx年xx月xx日
 *
 * @author  Begonia_sea
 * @create 2020-07-10 
 */
public class MyDate {
    private int year;
    private int month;
    private int day;

    public MyDate(int year, int month, int day) {
        this.year = year;
        this.month = month;
        this.day = day;
    }

    public MyDate() {
    }

    public int getYear() {
        return year;
    }

    public void setYear(int year) {
        this.year = year;
    }

    public int getMonth() {
        return month;
    }

    public void setMonth(int month) {
        this.month = month;
    }

    public int getDay() {
        return day;
    }

    public void setDay(int day) {
        this.day = day;
    }

    public String toDateString(){
        return year + "年" + month + "月" + day + "日";
    }
}



/**
 * 定义SalariedEmployee类继承Employee类,实现按月计算工资的员工处理。
 * 该类包括:private成员变量monthlySalary;
 * 实现父类的抽象方法earnings(),该方法返回monthlySalary值;
 * toString()方法输出员工类型信息及员工的name,number,birthday。
 *
 *
 * @author shkstart
 * @create 2020-07-10 14:46
 */
public class SalariedEmployee extends Employee {

    private double monthlySalary;//月工资

    public SalariedEmployee(double monthlySalary) {
        this.monthlySalary = monthlySalary;
    }

    public SalariedEmployee(String name, int number, MyDate birthday, double monthlySalary) {
        super(name, number, birthday);
        this.monthlySalary = monthlySalary;
    }

    public SalariedEmployee(String name, int number, MyDate birthday) {
        super(name, number, birthday);
    }

    public double getMonthlySalary() {
        return monthlySalary;
    }

    public void setMonthlySalary(double monthlySalary) {
        this.monthlySalary = monthlySalary;
    }

    @Override
    public double earnings() {
        return monthlySalary;
    }

    //toString()方法输出员工类型信息及员工的name,number,birthday
    @Override
    public String toString() {
        return "SalariedEmployee{" + super.toString() + "}";
    }
}


/**
 * (4)参照SalariedEmployee类定义HourlyEmployee类,实现按小时计算工资的员工处理。
 * 该类包括:
 * private成员变量wage和hour;
 * 实现父类的抽象方法earnings(),该方法返回wage*hour值;
 * toString()方法输出员工类型信息及员工的name,number,birthday。
 *
 *
 * @author  Begonia_sea
 * @create 2020-07-10 
 */
public class HourlyEmployee extends Employee {

    private int hour;//小时数
    private int wage;//单位小时的工资


    @Override
    public double earnings() {
        return hour * wage;
    }

    public HourlyEmployee() {
    }

    public HourlyEmployee(String name, int number, MyDate birthday) {
        super(name, number, birthday);
    }

    public HourlyEmployee(String name, int number, MyDate birthday, int hour, int wage) {
        super(name, number, birthday);
        this.hour = hour;
        this.wage = wage;
    }

    public int getHour() {
        return hour;
    }

    public void setHour(int hour) {
        this.hour = hour;
    }

    public int getWage() {
        return wage;
    }

    public void setWage(int wage) {
        this.wage = wage;
    }

    //toString()方法输出员工类型信息及员工的name,number,birthday。
    @Override
    public String toString() {
        return "HourlyEmployee{" + super.toString() + "}";
    }
}



import java.util.Scanner;

/**
 * 定义PayrollSystem类,创建Employee变量数组并初始化,该数组存放各类雇员对象的引用。
 * 利用循环结构遍历数组元素,输出各个对象的类型,name,number,birthday,以及该对象生日。
 * 当键盘输入本月月份值时,如果本月是某个Employee对象的生日,还要输出增加工资信息。
 *
 * @author  Begonia_sea
 * @create 2020-07-10
 */
public class PayrollSystem {
    public static void main(String[] args) {
        Employee[] emps = new Employee[2];

        emps[0] = new SalariedEmployee("杨超宇",1001,new MyDate(1994,4,02),20000);
        emps[1] = new HourlyEmployee("闫宏浩",1002,new MyDate(1988,7,10),240,100);

        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入当前的月份:");
        int month = scanner.nextInt();

        for (int i = 0; i < emps.length; i++) {
            System.out.println(emps[i]);
            double monthlyMoney = emps[i].earnings();
            if(month == emps[i].getBirthday().getMonth()){
                monthlyMoney += 200;
            }
            System.out.println("月工资为:" + monthlyMoney);
        }
    }
}

2:接口

  • 基本使用
/**
 * interface关键字的使用
 * 1. 我们使用interface来声明一个接口。
 *     接口与类,是Java中并列关系的两个结构。
 *
 * 2. 接口,可以理解为特定功能的封装。通过类实现接口的方法,进而体现功能的扩充。同时,还不
 * 影响此类单继承父类的情况。
 *     而且,一个类可以实现多个接口。
 * 3. 格式:class SubClass extends SuperClass implements 接口1,接口2,...
 *
 * 4. 关于接口的使用:
 *    JDK 7及之前:只能定义全局常量 和 抽象方法
 *         > 全局常量使用:public static final 修饰。也可以省略不写
 *         > 抽象方法使用:public abstract 修饰。也可以省略不写
 *
 *    JDK 8: 增加了对静态方法、默认方法的定义。
 *    JDK 9: 增加了对私有方法的定义。
 *
 * 5. 实现类在实现了接口之后,必须要实现接口中的所有抽象方法,方可实例化。
 *    否则,实现类如果没有实现接口中的所有抽象方法,则此实现类仍为抽象类。
 *
 *  6. 接口中不能定义构造器的。也就是说,接口不能实例化。
 *
 *  7. 类与接口之间是实现关系,而且是可以多实现的。
 *     接口与接口之间是继承关系,而且是可以多继承的。
 *
 *
 * 补充说明:
 * 类继承类的关系:is - a
 * 类实现接口的关系: like - a
 * 类及其属性的关系: has - a
 *
 * @author  Begonia_sea
 * @create 2020-07-10 
 */
  • 代码演示
public class InterfaceTest {
    public static void main(String[] args) {
        System.out.println(Flyable.MAX_SPEED);
//        Flyable.MAX_SPEED = 8000;
    }
}

interface Flyable{
    //全局常量
    public static final int MIN_SPEED = 1;
    int MAX_SPEED = 7900;
    //抽象方法
    public abstract void fly();

    void stop();
}
interface AttackAble{

    void attack();//攻击

}

abstract class Plane implements Flyable{

    @Override
    public void fly() {

    }

//    @Override
//    public void stop() {
//
//    }
}

class Bullet implements Flyable,AttackAble{

    @Override
    public void fly() {

    }

    @Override
    public void stop() {

    }

    @Override
    public void attack() {

    }
}




interface AA{

}

interface CC{


}
interface DD extends AA,CC{

}
  • 体会接口作为标准、规范的存在
/**
 * 1. 接口的本质是契约,标准,规范
 *
 * 2. 接口的使用:实现了多态性。
 *
 * 3. 匿名实现类的理解
 *
 * @author  Begonia_sea
 * @create 2020-07-10 
 */
public class USBTest {
    public static void main(String[] args) {
        Computer com = new Computer();
        //1.创建了接口的实现类的对象printer
        Printer printer = new Printer();
        com.transferData(printer);

        //2.创建了接口的实现类的匿名对象
        com.transferData(new Flash());

        //3. 创建接口的匿名实现类的对象
        USB camera = new USB(){
            @Override
            public void start() {
                System.out.println("照相机开始工作");
            }

            @Override
            public void stop() {
                System.out.println("照相机结束工作");
            }
        };

        com.transferData(camera);

        //4. 创建接口的匿名实现类的匿名对象
        com.transferData(new USB(){
            @Override
            public void start() {
                System.out.println("mp3开始工作");
            }

            @Override
            public void stop() {
                System.out.println("mp3结束工作");
            }
        });
    }
}

class Computer{

    public void transferData(USB usb){ //体现了多态性。

        usb.start(); //虚方法调用

        System.out.println("========具体的数据传输细节=======");

        usb.stop();
    }

}
interface USB{
    void start();

    void stop();
}

class Printer implements USB{ //打印机

    @Override
    public void start() {
        System.out.println("打印机开始工作");
    }

    @Override
    public void stop() {
        System.out.println("打印机结束工作");
    }
}

class Flash implements USB{//U盘

    @Override
    public void start() {
        System.out.println("U盘开始工作");
    }

    @Override
    public void stop() {
        System.out.println("U盘结束工作");
    }
}
  • java8中接口的新特性


import java.net.SocketTimeoutException;

/**
 * @author  Begonia_sea
 * @create 2020-07-10 
 * */
public interface CompareA {

    public static void method1() {
        System.out.println("CompareA:北京");
    }

    public default void method2() {
        System.out.println("CompareA:上海");

    }

    default void method3() {
        System.out.println("CompareA:广州");
    }

    public default void method4(){
        System.out.println("CompareA:深圳");
    }

}



/**
 * @author  Begonia_sea
 * @create 2020-07-10 
 */
public interface CompareB {
    public default void method2() {
        System.out.println("CompareB:上海");
    }
}


/**
 * @author  Begonia_sea
 * @create 2020-07-10 
 */
public class SuperClass {

    public void method4(){
        System.out.println("SuperClass:深圳");
    }
}

/**
 * @author  Begonia_sea
 * @create 2020-07-10 
 */
public class SubClass extends SuperClass implements CompareA,CompareB {
    public void method3() {
        System.out.println("SubClass:广州");
    }

    public void method4(){
        System.out.println("SubClass:深圳");
    }

    public void method2() {
        System.out.println("SubClass:上海");
    }

    public void method(){
        //6. 如何在子类(或实现类)中调用父类或接口中被重写的方法
        //调用父类的方法:
        super.method4();
        //调用接口中的方法:
        CompareA.super.method2();
        CompareB.super.method2();

    }
}



/**
 * @author  Begonia_sea
 * @create 2020-07-10
 */
public class SubClassTest {
    public static void main(String[] args) {

        //1. 接口中静态方法的调用:只能使用接口本身来调用,其实现类不可以调用。
        CompareA.method1();
//        SubClass.method1();

        //2. 可以通过实现类的对象,调用接口中的默认方法
        SubClass sub1 = new SubClass();
        sub1.method2();
        //3.实现类可以重写接口中的默认方法。
        sub1.method3();

        //4.如果子类(或实现类)继承的父类和实现的接口中声明了同名同参数的方法,则子类在没有
        //重写此方法的情况下,默认调动的是父类中声明的方法。--->类优先原则
        //补充:如果子类(或实现类)重写了上述的方法,则调用的就是自己重写的方法。
        sub1.method4();

        //5.如果实现类实现了多个接口,且多个接口中声明了同名同参数的方法。则
        //子类必须重写此方法。否则,编译不通过。 --->接口冲突。
        sub1.method2();

        //6. 见SubClass内
        sub1.method();
    }
}

3:内部类

  • 基本知识点
/**
 * 类的成员之五:内部类
 *
 * 1. 分类:
 *   成员内部类:直接声明在外部类的内部。
 *
 *   局部内部类:声明在方法内、代码块内等的内部类。
 *
 * 2. 关于成员内部类的使用:
 *    2.1 作为外部类的一个成员:
 *    > 可以使用4种不同的权限进行修饰
 *    > 可以使用static进行修饰
 *    > 可以在内部类中调用外部类的成员
 *
 *    2.2 作为类的:
 *    > 可以在内部声明属性、方法、构造器、代码块、内部类....
 *    > 可以被abstract、final修饰。
 *
 *
 *
 * 3. 学习内部类需要掌握的三个知识点
 * ① 如何创建成员内部类的对象
 * ② 如何在成员内部类中调用外部类的属性、方法
 * ③ 熟悉局部内部类的基本使用: 见 InnerClassTest1.java
 *
 * @author  Begonia_sea
 * @create 2020-07-10 
 */
  • 代码举例

    • 外部类的使用

      public class InnerClassTest {
          public static void main(String[] args) {
              //创建静态的成员内部类
              Person.Bird bird = new Person.Bird();
              //创建非静态的成员内部类
              Person p = new Person();
              Person.Dog dog = p.new Dog();
      
              dog.info();
              dog.show("旺财");
          }
      }
      
      
      class Person{
          String name = "小明";
          int age = 1;
          //静态的成员内部类
          static class Bird{
      
          }
          //非静态的成员内部类
          class Dog{
              String name = "小花";
      
              public void info(){
                  //直接调用外部类的属性和方法
                  System.out.println(age);
                  Person.this.eat();
              }
      
              public void show(String name){
                  System.out.println(name);
                  System.out.println(this.name);
                  System.out.println(Person.this.name);
              }
      
              public void eat(){
                  System.out.println("狗吃骨头");
              }
          }
      
          public void eat(){
              System.out.println("人吃饭");
          }
      
      }
      
    • 内部类的使用

      
      
      /**
       * 体会局部内部类的使用
       *
       * @author  Begonia_sea
       * @create 2020-07-10 
       */
      public class InnerClassTest1 {
      
          //此种方式使用局部内部类:不常见
          public void method(){
              //声明一个局部内部类
              class A{
      
              }
          }
      
          //常见如下的操作:
          public Comparable getComparable(){
              //方式一:
              /*//内部声明一个接口的实现类
              class MyComparable implements Comparable{
      
                  @Override
                  public int compareTo(Object o) {
                      return 0;
                  }
              }
      
              return new MyComparable();*/
      
              //方式二:创建了接口的匿名实现类的匿名对象
              return new Comparable(){
      
                  @Override
                  public int compareTo(Object o) {
                      return 0;
                  }
              };
          }
      
      }
      
      
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值