2022-07-26 张明旭 抽象、接口、栈、队列学习记录

发布于:2022-07-26 ⋅ 阅读:(428) ⋅ 点赞:(0)

目录

心情感悟

知识点

面向对象的第四大特征:抽象

抽象方法:(没有大括号,没有方法体)

抽象方法的根本意义

抽象方法约定了什么

《 抽象方法必须在一个抽象类(或接口)里!!!》

abstract关键字

总结:

接口

接口的声明

JDK版本更迭对接口的影响

接口中结构的特点

接口的意义

三中编程(了解)

接口可以被实现:实现类

面试题

面试题

匿名实现类

栈和队列

受限表现在什么地方

栈和队列的相同点

栈和队列的不同点

栈的基本操作

队列的基本操作


心情感悟

今天又学了一大堆药来回调用的东西,这是面向对象的最后一大特征了,学废了,面向对象阶段的调用真的不好捋清楚。我的头发无了。。。

知识点

面向对象的第四大特征:抽象


Java中除了类之外,还有抽象类和接口

抽象方法:(没有大括号,没有方法体)


父类方法需要重写时;可以 不输出任何东西,可以不加大括号直接定义,但需要用abstract关键字。

public abstract void eat();

抽象方法的根本意义


一种约定,自定义一个抽样方法的规则,从而控制子类重写抽样方法的规则

抽象方法约定了什么


约定了子类重写方法时的返回权限、访问权限、参数列表,且需要在重写时定义方法体

《 抽象方法必须在一个抽象类(或接口)里!!!》

public abstract class Animal {}

1.一个抽象类里可以有哪些结构?

  • 属性

  • 成员方法

  • 构造器

  • 抽象方法

  • 常量

2.抽象类中能不能没有抽象方法?

  • 抽象类可以没有抽象方法,但是如果一个类中没有抽象方法,尽量不要定义成抽象类

3.抽象类不能被实例化:

  • 抽象类不能创造对象
        /*
          抽象类不能被实例化 = 抽象类不能创造对象
         */
// 报错:       Animal animal = new Animal() ;

4.抽象类构造器存在意义

  • 为了约定子类的构造器必须和父类匹配

5.一个(非抽象类)子类继承的是一个抽象类,则抽象类中的全部抽象方法,必须在子类中重写。

例如:

Animal类为父类,其中有eat()方法,show()方法。Person为子类,则子类中必须有这两种方法的重写!!

public abstract class Animal {

    private String name;
    private Integer age;

    public abstract void eat();

    public abstract void show();

    public Animal() {
    }
public class Person extends Animal{

    @Override
    public void eat(){
        System.out.println("人在猛炫饭");
    }

    @Override
    public void show() {
        System.out.println("。。。没什么展示的,给大家劈个叉。。。");
    }

abstract关键字


abstract修饰:

  • 方法

  • 抽象方法能不能用private修饰?----不能,开发中,抽象方法基本上都是public
  • 抽象方法能不能用final修饰?------不能,final修饰的方法不能被重写,抽象方法的意义为让子类重写
  • 抽象类能不能用final修饰?--------不能,final修饰的类不能被继承,抽象方法的意义为让子类继承

总结:


1.抽象方法必须是public或者protected,默认情况其实就是public,如果是private,不能被子类继承,无法实现该方法


2.抽象类不能被直接实例化,需要依靠子类采用向上转型的方式处理


3.抽象类存在的意义:必须要有子类,一个类只能继承一个(抽象)类


4.子类(如果不是抽象类),则必须重写父类抽象类中所有的抽象方法
  如果子类没有完全实现抽象类方法,则子类也要被定义成抽象类

案例类:Person、Animal、AnimalSon

  • 定义Animal抽象类;
  • 定义Person类继承Animal类,体现抽象类的一些性质。
  • AnimalSon类表示:抽象类继承抽象类

案例完整代码:

Animal类:

public abstract class Animal {

    private String name;
    private Integer age;

    public abstract void eat();

    public abstract void show();

    public Animal() {
    }

    public Animal(String name, Integer age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

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

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }
}

Person类:

public class Person extends Animal{

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

    @Override
    public void show() {
        System.out.println("。。。。。。");
    }

    public void drank() {
        System.out.println("人在喝酒");
    }
}

AnimalSon类:

public abstract class AnimalSon extends Animal{
}

接口

  • 比抽象类更高级的抽象

接口的声明


interface关键字:

  • 用来创建接口类。

形式:

public interface ch02

JDK版本更迭对接口的影响

  • JDK1.7之前:接口中只能有抽象方法、静态常量、静态方法,不能有属性、方法
  • JDK8及以后:接口中有抽象方法,默认方法和静态方法,静态常量

接口中结构的特点

  • 接口中的抽象方法默认为,推荐省略

       “public abstract”

  • 接口中的常量默认是,建议省略

       “public static final”

  • 接口中的结构必须是

       “public”

接口的意义

  • 约定:同抽象方法约定的意义

三中编程(了解)

  • 面向对象编程
  • 面向接口编程:主要写接口(根据需求定义接口,难)
  • 面向切面编程(难难)

接口可以被实现:实现类

实现类

  • 比如 “类A implements 接口”,那我们就说A是这个接口的实现类。

例如:Biology类是一个接口,则下码Animal为实现类(实现接口中方法的类)。

public class Animal implements Biology{}

性质

  • 如果一个类实现了一个接口,它就需要重写接口中所有的抽象方法
  • 实现接口可以实现多个,继承只能单继承
  • 开发中,如果一件事可以通过继承和实现接口解决问题,用接口解决

补充

多态的前提条件?
1.继承。实现
2.重写方法
3.父类--》子类;接口--》实现类

面试题


1.继承抽象类和实现接口的异同
异:继承单继承,接口多实现
同:都需要重写所有的抽象方法
2.抽象类和接口的区别
抽象类包含的东西多
接口只有抽象方法、静态常量、静态方法、默认方法

面试题


在Java中只有单继承?
错,Java中存在多继承
接口和接口之间有多继承

类与类之间单继承

案例类:Biology、Cat、CatsAnimal、Animal

Biology类:

public interface Biology {

    // 静态常量
    public static final String NAME = "张三";
    // 抽象方法
    public abstract void breath();
    // 抽象方法
    public abstract void eat();
    // 静态方法
    public static void show(){

    }
    // 默认方法
    // 谁可以调用它
    public default void info(){

    }
}

Cat类:

/*
  这个Cat类就继承了Animal类同时实现了Biology接口
  Cat类就可以叫做Animal类的子类
  也可以叫做Biology类的实现类
*/
public class Cat extends Animal implements Biology,CatsAnimal {

    @Override
    public void breath() {

    }

    @Override
    public void show() {

    }

    @Override
    public void eat() {

    }
}

CatsAnimal类:

public interface CatsAnimal {
}


匿名实现类

  • 形式:


父类 对象---》无名的实现类{
重写的方法
}

  • 接口形式同上

一般用有名的实现类

*/
public class Ch01 {
    public static void main(String[] args) {
        Ch01 ch01 = new Ch01();

        Abstr01 a01 = new Abstr01() {
            //这里是个无名的类,可以有属性方法等
            @Override
            public void show() {
                System.out.println("重写过后的show方法");
            }
        };
        a01.show();
        System.out.println(a01);
        Inter01 inter01 = new Inter01() {
            @Override
            public void eat() {
                System.out.println("重写过后的eat方法");
            }
        };
        //有名的实现类
        Abstr01 a02 = new Ch02();
    }
}


栈和队列

  • 栈和队列是两种操作受限的线性表

受限表现在什么地方

  • 栈的插入和删除只允许在表的尾端进行(栈中叫“栈顶”),满足FILO(first in last out)
  • 队列只允许在表位插入元素,在表头删除元素,FIFO(first in first out)

栈和队列的相同点


1.都是线性结构
2.插入的操作都是在表尾进行
3.都可以通过顺序结构和链式结构实现
(假设昨天的,也就是我上个博客的单向链表:superlinked为基础,构成一个栈和一个队列,完成栈和队列的一些基本操作)

栈和队列的不同点

  • 栈:先进后出;
  • 队列:先进先出



栈的基本操作

public class Stack {
    private SuperLinked superLinked = new SuperLinked();
    //入栈,压栈
    public void push(Integer i){
        superLinked.add(i);
    }

    //返回栈顶元素,不出栈
    public Integer peek(){
        if (empty()){
            return null;
        }
        return superLinked.get(superLinked.size() - 1);
    }

    //出栈,从栈尾出去
    public boolean pop(){
        if (empty() == false){
            return superLinked.removeLast();
        }
        return false;
    }

    private boolean empty(){
        return superLinked.size() == 0;
    }

    public static void main(String[] args) {
        // 测试
        Stack stack = new Stack();
        stack.push(1);
        stack.push(2);
        stack.push(3);
        stack.push(4);

        stack.pop();

        System.out.println(stack.peek());
    }

队列的基本操作

public class Queue {
    private SuperLinked superLinked = new SuperLinked();
    //入队的方法
    public void add(Integer item){
        superLinked.add(item);
    }

    //出队的方法

    public Integer poll(){
        //1.判断这个队列是不是空
        if (empty()){
            return null;
        }

        //2.找到队列的头
       Integer integer  =  superLinked.get(0);
        //3.把队伍的头删掉
        superLinked.removeHead();
        //4.返回删除的值
        return integer;
    }

    //返回队首,不出队
    public Integer peek(){
        if (empty()){
            return null;
        }
        return superLinked.get(0);
    }

    //判断这个队列是否为空
    public boolean empty(){
//        if (superLinked.size() == 0){
//            return true;
//        }else{
//            return false;
//        }
       return superLinked.size() == 0;
    }

    public static void main(String[] args) {
        Queue queue = new Queue();
        queue.add(1);
        queue.add(120);
        queue.add(50);

        queue.poll();

        System.out.println(queue.peek());
    }
}


网站公告

今日签到

点亮在社区的每一天
去签到