面向对象--抽象 : abstract
类,抽象类,接口,
抽象方法没有大括号(方法体)
抽象方法的意义:
根本意义是 约定'(自定义的规则)
约定了什么?定了哪些规则?
子类重写方法,返回值一样,访问权限,参数列表,需要在重写的时候定义方法体
有抽象方法必须是抽象类,
当我们定义了一个抽象类,类中能有哪些结构?
属性,成员方法,构造器,抽象方法,常量
抽象类可以没有抽象方法,
约定大于配置,配置大于编码
1,抽象类不能被实例化,不能创建对象,子类向上转型可以
2,构造方法和类方法(被static修饰的方法)不能声明为抽象方法
接口不能有构造器(interfaces cannot have constructors)
构造方法用于初始化成员变量,但是接口成员变量是常量,无需修改,类可以实现多个接口,如果接口都有自己的构造器,那么决定不了构造器链的调用顺序
构造器是属于类自己的,不能继承,因为接口是纯虚的,不需要构造器
抽象类的构造器存在的意义?
为了约定子类的构造器必须和父类匹配
一个类继承抽象类,必须重写抽象类的所有的抽象方法,除非子类是抽象类
abstract能修饰什么?
类,方法
抽象方法能不能被private修饰? 不可以,其他可以,开发中,基本上都写public
抽象方法能不能被final修饰? 不能,final修饰的方法不能被重写,抽象类也不能用final修饰,修饰的类不能被继承,
构造方法只有一种写法,前面什么都不能加
抽象方法必须是public /protected/(如果是private不能被子类继承,子类无法实现该方法)
接口 interface
jdk7以前
接口中只能只能有抽象方法,只能有静态常量
1,
2,
jdk8及以后
可以有默认方法(default),静态方法和静态常量,抽象方法
1,
2,
3,
4,
抽象类比类抽象,接口比抽象类更高级的抽象
接口中的方法默认是public abstract只能是public
接口中的常量默认是 public static final
接口中的结构必须是public
面向对象编程
面向接口编程(主要写接口)
面向切面编程
多态的前提条件
1,继承,实现
2,重写方法
3,父类对象指向子类引用
接口可以多继承,继承接口,类与类之间只有单继承
接口和抽象类的区别:
1,接口不能有构造方法,抽象类可以有
2,接口不能有方法体,抽象类可以有
3,接口中变量必须是public static final, 抽象类中没有要求
Static
static的主要意义是创建独立于具体对象的域变量或者方法,以至于即使没有创建对象,也能使用属性和方法.
静态的变量或者方法存在于方法区,静态的结构不会被垃圾回收,调用静态结构直接用 "类名."的方式
实例方法和静态方法互相调用:
在静态方法中不可以直接调用实例方法,只能创建对象调用
实例方法中可以直接调用静态方法
同一个类中静态方法互相调用可以省略类名
开发中,常量的声明基本都是public static final
静态方法没有重写的概念
设计工具类的时候可以用到static
形成静态代码块以优化程序性能,每个static代码块只会执行一次,很多时候会将一些只需要进行一次的初始化操作放在static代码块中进行.
被static修饰 的变量或者方法是独立于该类的任何对象,这些变量和方法不属于任何一个实例对象,而是被类的实例对象所共享,
static变量值在类加载的时候分配空间,以后创建类对象的时候不会重新分配
被static修饰的变量或者方法是优先于对象存在的,当一个类加载完毕之后,即使没有创建对象,也可以去访问
static 如果使用,则该方法必须有方法体,也就不再是抽象方法。static嘛,程序运行就加载的,所以要有方法体。
如果哪个成员是被所有对象所共享的,那么就该定义为静态的,
常见的有:
1,修饰成员变量
2,修饰成员方法
3,修饰类(只能修饰内部类)
4,静态导包
5,代码块'
静态变量和实例变量的区别?
静态变量是属于这个类,而不属于某个对象
不被static修饰的成员变量叫做实例变量,实例变量是属于这个类的实例对象,
static不允许修饰局部变量
静态变量属于类的,在内存中只有一份,在类的加载过程中,jvm只为静态变量分配一次内存空间
实例变量每次创建对象,都会为每个对象分配成员变量内存空间,实例变量属于实例对象,在内存中,创建几次对象,就有几份成员变量
匿名实现类
package com.jsoft.afternoon;
public abstract class Abstr01 {
public abstract void show();
}
package com.jsoft.afternoon;
/**
* 匿名实现类
*
*/
public class Ch01 {
public static void main(String[] args) {
Ch01 ch01 = new Ch01();
System.out.println("ch01=" + ch01);
Abstr01 a01 = new Abstr01() {
@Override
public void show() {
System.out.println("重写过后的show方法...");
}
};
a01.show();
Abstr01 abstr02 = new Ch02();
System.out.println(a01);
Inter01 inter01 = new Inter01() {
@Override
public void eat() {
System.out.println("重写过后的eat方法...");
}
};
}
}
package com.jsoft.afternoon;
import com.jsoft.afternoon.Abstr01;
public class Ch02 extends Abstr01 {
@Override
public void show() {
}
}
栈和队列:
栈和队列是两种操作受限的线性表
这种受限表现在:栈的插入和删除只允许在表的尾端进行(在栈中叫做栈顶)
基于单向链表的栈代码实现
package com.jsoft.afternoon;
import com.jsoft.afternoon.linked.SuperLinked;
/**
* 栈和队列:
* 栈和队列是两种操作受限的线性表。
*
* 这种受限表现在:
* 栈的插入和删除只允许在表的尾端进行(在栈中叫做“栈顶”),满足FILO
* First In Last Out;
* 队列只允许在表位插入元素,在表头删除元素,FIFO First In First Out
*
* 栈与队列的相同点:
* 1.都是线性结构
* 2.插入操作都是在表尾进行
* 3.都可以通过顺序结构和链式结构实现。
*
* 栈与队列的不同点:
* 1.队列,先进先出,栈先进后出
*
*/
public class Stack {
private SuperLinked superLinked = new SuperLinked();
// 入栈。压栈
public void push(Integer item){
superLinked.add(item);
}
// 返回栈顶元素,不出栈
public Integer peek(){
if(empty()) {
return null;
}
return superLinked.get(superLinked.size() - 1);
}
// 出栈,从栈尾出去
public Integer pop(){
if(empty()) {
return null;
}
Integer integer = superLinked.get(superLinked.get(superLinked.size() - 1));
superLinked.remove(superLinked.size() - 1);
return integer;
}
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());
}
}
队列的代码实现
package com.jsoft.afternoon;
import com.jsoft.afternoon.linked.SuperLinked;
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.removeFirst();
// 4.返回删除的值
return integer;
}
// 返回队首,不出队
public Integer peek() {
if(empty()) {
return null;
}
return superLinked.get(0);
}
// 判断这个队列是否为空
public boolean empty() {
// if(superLinked.size() == 0){
// return true;
// }
// 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());
}
}
一个队列应用例子
package com.jsoft.afternoon.test03;
import com.jsoft.afternoon.Queue;
import com.jsoft.morning.B;
import java.util.Scanner;
/**
* 银行取票机
* 队列
*
*/
public class BankTicketMachine {
// 需要一个队列结构
private Queue queue = new Queue();
// 银行的小票起始号
private int startNumber = 100;
private Scanner scanner = new Scanner(System.in);
// 取票
public Integer getTicket(){
if(queue.empty()){
System.out.println("号码已经全部领取,需要继续释放号码!");
System.out.println("请输入释放号码的个数:");
Integer number = scanner.nextInt();
pushTicket(number);
}
return queue.poll();
}
// 排队
public void pushTicket(int ticketNumber){
for (int i = 0;i < ticketNumber;i++){
startNumber += 1;
queue.add(startNumber);
}
}
public void run() {
while(true) {
System.out.println("请输入您的名字:");
String name = scanner.next();
Integer ticket = getTicket();
System.out.println("尊敬的【"+ name+ "】,您的号码是:" + ticket + "。");
}
}
public static void main(String[] args) {
// BankTicketMachine bankTicketMachine = new BankTicketMachine();
new BankTicketMachine().run();
}
}