目录
心情感悟
今天又学了一大堆药来回调用的东西,这是面向对象的最后一大特征了,学废了,面向对象阶段的调用真的不好捋清楚。我的头发无了。。。
知识点
面向对象的第四大特征:抽象
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());
}
}