每日一考和复习
每日一考
- static修饰的属性,相较于实例变量,有哪些特别之处(>=3点)
1.不需要实例化对象,可以直接由“类名.属性”调用(有权限)
2.所有由这个类实例化出来的对象共享静态属性
3.不可以被非静态的方法调用
4.随着类的加载而加载
- final 可以用来修饰哪些结构,分别表示什么意思
1.类 不可以被继承
2.方法 不可以被重写
3.变量 不可以被修改
4.代码块 声明类时优先加载静态代码块
- 代码实现单例模式的饿汉式
class Bank {
private Bank() {}
private static Bank instance = new Bank();
public static Bank getInstance() {
return instance;
}
}
- 代码实现单例模式的懒汉式 -目前还是线程不安全的
class Order {
private Order() {}
private static Order instance = null;
public static Order getInstance() {
if (instance == null) {
instance = new Order();
}
return instance;
}
}
- 类的属性赋值的位置有哪些?先后顺序为何?
1.默认初始化
2.显式初始化
3.构造器
4.对象.属性、对象.方法
5.代码块
先后顺序:
1->2/5->3->4
复习
day14的学习内容
面向对象
抽象类和抽象方法
abstract关键字的使用
-
abstract:抽象的
-
abstract可以用来修饰的结构:类、方法
-
abstract修饰类:抽象类
- 此类不能实例化
- 抽象类中一定有构造器,便于子类实例化时调用(涉及:子类对象实例化的全过程)
- 开发中,都会提供抽象类的子类,让子类对象实例化,完成相关的操作
-
abstract修饰方法:抽象方法
- 抽象方法只有方法的声明,没有方法体
- 包含抽象方法的类,一定是一个抽象类。反之,抽象类中可以没有抽象方法的。
- 若子类重写了父类中的所有的抽象方法后,此子类方可实例化
若子类没有重写父类中的所有的抽象方法,则此子类也是一个抽象类,需要使用abstract修饰
-
abstract使用上的注意点:
- abstract不能用来修饰:属性、构造器等结构
- abstract不能用来修饰私有方法、静态方法、final的方法、final的类(static方法同名同参数列表不叫重写)
抽象方法设计模式
- 当功能内部一部分实现是确定的,一部分实现是不确定的。这时可以把不确定的部分暴露出去,让子类去实现
简单的例子
public class TemplateTest {
public static void main(String[] args) {
SubTemplate t = new SubTemplate();
t.spendTime();
}
}
abstract class Template {
// 计算某段代码执行所需要花费的时间
public void spendTime() {
long start = System.currentTimeMillis();
this.code();// 不确定的部分、易变的部分
long end = System.currentTimeMillis();
System.out.println("花费的时间为:" + (end - start));
}
public abstract void code();
}
class SubTemplate extends Template {
@Override
public void code() {
for (int i = 2; i <= 1000; i++) {
boolean isFlag = true;
for (int j = 2; j <= Math.sqrt(i); j++) {
if (i % j == 0) {
isFlag = false;
break;
}
}
if (isFlag) {
System.out.println(i);
}
}
}
}
接口
-
接口使用interface来定义
-
Java中,接口和类是并列的两个结构
-
如何定义接口:定义接口中的成员
3.1 JDK7及以前:只能定义全局常量和抽象方法
->全局常量:public static final的.但是书写时,可以省略不写
->抽象方法:public abstract的3.2 JDK8:除了定义全局常量和抽象方法之外,还可以定义静态方法、默认方法(略)
-
接口中不能定义构造器的!意味着接口不可以实例化
-
Java开发中,接口通过让类去实现(implements)的方式来使用
如果实现类覆盖了接口中的所有抽象方法,则此实现类就可以实例化
如果实现类没有覆盖接口中所有的抽象方法,则此实现类仍为一个抽象类 -
Java类可以实现多个接口—>弥补了Java单继承性的局限性
格式:class AA extends BB implements CC,DD,EE -
接口与接口之间可以继承,而且可以多继承
- 接口的具体使用,体现多态性
- 接口,实际上可以看做是一种规范
- 接口的使用
1.接口使用上也满足多态性
2.接口,实际上就是定义了一种规范
3.开发中,体会面向接口编程!
public class USBTest {
public static void main(String[] args) {
Computer com = new Computer();
// 1.创建了接口的非匿名实现类的非匿名对象
Flash flash = new Flash();
com.transferData(flash);
// 2. 创建了接口的非匿名实现类的匿名对象
com.transferData(new Printer());
// 3. 创建了接口的匿名实现类的非匿名对象
USB phone = new USB() {
@Override
public void start() {
System.out.println("手机开始工作");
}
@Override
public void stop() {
System.out.println("手机结束工作");
}
};
com.transferData(phone);
// 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 usb = new Flash();
usb.start();
System.out.println("具体传输数据的细节");
usb.stop();
}
}
interface USB {
// 常量:定义了长、宽、最大最小的传输速度等
void start();
void stop();
}
class Flash implements USB {
@Override
public void start() {
System.out.println("U盘开启工作");
}
@Override
public void stop() {
System.out.println("U盘结束工作");
}
}
class Printer implements USB {
@Override
public void start() {
System.out.println("打印机开启工作");
}
@Override
public void stop() {
System.out.println("打印机结束工作");
}
}
代理模式
-
代理设计就是为其他对象提供一种代理以控制对这个对象的访问
-
应用场景:
-> 安全代理:屏蔽对真实角色的直接访问
-> 远程代理:通过代理类处理远程方法调用(RMI)
->延迟加载:先加载轻量级的代理对象,真正需要再加载真实对象比如你要开发一个大文档查看软件,大文档中有大的图片,有可能一个图片有100MB,在打开文件时,不可能将所有的图片都显示出来,这样就可以使用代理模式,当需要查看图片时,用proxy来进行大图片的打开 -
分类
-> 静态代理(静态定义代理类)
-> 动态代理(动态生成代理类)
JDK自带的动态代理,需要反射等知识
public class StaticProxyTest {
public static void main(String[] args) {
Proxy s = new Proxy(new RealStar());
s.confer();
s.signContract();
s.bookTicket();
s.sing();
s.collectMoney();
}
}
interface Star {
void confer();// 面谈
void signContract();// 签合同
void bookTicket();// 订票
void sing();// 唱歌
void collectMoney();// 收钱
}
//被代理类
class RealStar implements Star {
public void confer() {
}
public void signContract() {
}
public void bookTicket() {
}
public void sing() {
System.out.println("明星:歌唱~~~");
}
public void collectMoney() {
}
}
//代理类
class Proxy implements Star {
private Star real;
public Proxy(Star real) {
this.real = real;
}
public void confer() {
System.out.println("经纪人面谈");
}
public void signContract() {
System.out.println("经纪人签合同");
}
public void bookTicket() {
System.out.println("经纪人订票");
}
public void sing() {
real.sing();
}
public void collectMoney() {
System.out.println("经纪人收钱");
}
}
类的成员之五:内部类
类的内部成员之五:内部类
-
Java中允许将一个类A声明在另一个类B中,则类A就是内部类,类B称为外部类
-
内部类的分类:成员内部类(静态、非静态) vs 局部内部类(方法内、代码块内、构造器内)
-
成员内部类:
一方面,作为外部类的成员:
-> 调用外部类的结构
-> 可以被static修饰
-> 可以被4种不同的权限修饰另一方面,作为一个类:
-> 类内可以定义属性、方法、构造器等
-> 可以被final修饰,表示此类不能被继承。言外之意,不使用final,就可以被继承
-> 可以被abstract修饰 -
关注如下的3个问题
4.1 如何实例化成员内部类的对象
4.2 如何在成员内部类中区分调用外部类的结构
4.3 开发中局部内部类的使用
public class InnerClassTest {
public static void main(String[] args) {
// 创建Dog实例(静态的成员内部类):
Person.Dog dog = new Person.Dog();
dog.show();
// 创建Bird实例(非静态的成员内部类):
// Person.Bird bird = new Person.Bird();//错误的
Person p = new Person();
Person.Bird bird = p.new Bird();
bird.sing();
System.out.println();
bird.display("黄鹂");
}
}
class Person {
String name = "小明";
int age;
public void eat() {
System.out.println("人:吃饭");
}
// 静态成员内部类
static class Dog {
String name;
int age;
public void show() {
System.out.println("卡拉是条狗");
// eat();
}
}
// 非静态成员内部类
class Bird {
String name = "杜鹃";
public Bird() {
}
public void sing() {
System.out.println("我是一只小小鸟");
Person.this.eat();// 调用外部类的非静态属性
eat();
System.out.println(age);
}
public void display(String name) {
System.out.println(name);// 方法的形参
System.out.println(this.name);// 内部类的属性
System.out.println(Person.this.name);// 外部类的属性
}
}
}