文章目录
main方法
程序入口,是一个普通的静态方法。可作为我们与控制台交互的方式
抽象类和抽象方法(abstract)
类的设计应该保证父类和子类能够共享特征,以至于其没有具体实例。这样的类就叫做抽象类
abstract可以用来修饰类【不能修饰final】、方法【不能修饰private、static、final】。
修饰类:
- 此类不能实例化
- 抽象类中必有构造器,便于子类实例化时调用
- 开发中都会提供抽象类的子类,让子类对象实例化
- 抽象类中可以没有抽象方法
修饰方法:
- 抽象方法只有声明,没有方法体
public abstract void eat();
- 包含抽象方法的类一定是一个抽象类
- 若子类重写父类中的所有抽象方法后,子类方能实例化
- 若子类没有重写父类中的所有抽象方法,则此子类是一个抽象类
抽象类的匿名子类
当Employee为抽象类时,可以创建一个匿名子类并new出对象
Employee employee=new Employee() {
//重写Employee的抽象方法
@Override
public void work() {
System.out.println("工作");
}
};
设计模式:模板方法(TemplateMethod)
当功能内部一部分实现是确定的,一部分是不确定的。此时可以把不确定的部分暴露出去让子类实现。
**abstract class Template{
//计算某段代码执行所需花费的时间
public void spendTime(){
long start=System.currentTimeMillis();
code();//不确定、易变的部分
long end=System.currentTimeMillis();
System.out.println("花费时间为"+(end-start));
}
public abstract void code();
}**
接口(interface)
继承:“是不是”;接口:“能不能”。不同类都具有的功能
-
接口和类是并列的两个结构
-
版本差异
≤JDK7:只能定义全局常量和抽象方法
全局常量:public static final【可省略】
抽象方发:public abstract【可省略】
≥JDK8:除了上述方法外,还能定义静态方法、默认方法
interface Run{ //静态方法【只能通过接口来调用Run.method1()】 public static void method1(){ System.out.println("静态方法"); } //抽象方法 public abstract void method2(); //默认方法 public default void method3(){ System.out.println("默认方法"); } }
-
接口中不能定义构造器—>接口不能实例化
-
开发中,接口通过让类实现(implements)来使用
若实现类覆盖了接口中所有抽象方法则能被实例化
否则此实现类仍为抽象类
-
可以实现多个接口—>弥补了Java单继承的局限性
class AA extends BB implements CC,DD,EE
-
接口与接口之间可以多继承
-
接口具体的使用,体现了多态性
-
接口是一种规范【面向接口编程】
使用不同数据库进行操作时代码不同。实际使用时,将接口定义为形参即可操作。具体代码各个数据库内部将接口进行实现即可。
-
父类与接口冲突
调用同名属性时,父类:super.x;接口:接口.x
调用同名同参方法时,若未进行重写,默认调用父类方法
调用重写后方法:method()
调用父类方法:super.method()
调用接口方法:接口.super.method()
-
接口与接口冲突
调用同名同参的默认方法时,出现接口冲突,报错
代理模式(Proxy)
为其他对象提供一种代理以控制对该对象的访问
被代理类完成核心功能
其余杂项及额外功能交予代理类做
例:接口star有面谈、签合同、订票、唱歌、收钱的抽象方法
implement Star{}
被代理类:歌星A实现接口,其中仅需完成核心功能唱歌
class RealStarA implements Star{}
代理类:实现接口的所有方法,其中唱歌方法通过调用被代理类的唱歌方法即可
class Proxy implements Star{}
当被代理类的对象歌星A被替换成歌星B,代理类无需修改,仅需将代理类歌星B的核心方法进行修改即可。
class RealStarB implements Star{}
public class Test {
public static void main(String[] args) {
//创建被代理类的对象server
Server server=new Server();
/*
创建代理类的对象proxyServer
将server赋给了proxyServer的netWork
*/
ProxyServer proxyServer=new ProxyServer(server);
proxyServer.browse();
}
}
interface NetWork{
void browse();
}
//被代理类
class Server implements NetWork{
@Override
public void browse() {
System.out.println("真实的服务器访问网络");
}
}
//代理类
class ProxyServer implements NetWork{
private NetWork netWork;
public ProxyServer(NetWork netWork){
this.netWork=netWork;
}
public void check(){
System.out.println("联网前的检查工作");
}
@Override
public void browse() {
check();
netWork.browse();
}
}
应用场景
- 安全代理:屏蔽对真实对象的直接访问
- 远程代理:通过代理类处理远程方法调用(RMI)
- 延迟加载:先加载轻量级的代理对象,真正需要时再加载真实对象
- 开发一个大文档查看软件,其中有大的图片,打开文件时不可能显示所有图片,可以使用代理模式,先加载主要的东西,需要查看图片时,用proxy来进行大图片的打开
- 静态代理(静态定义代理类)
- 动态代理(动态生成代理类)
- JDK自带的动态代理,需要反射等知识
工厂模式(Factory)
实现创建者与调用者的分离
简单工厂模式
新产品的加入要修改工厂的判断语句
class CarFactory{
//方式一
public static Car getCar(String type){
if("奥迪".equals(type)){
return new Audi();
}
else if("比亚迪".equals(type)){
return new BYD();
}
else{
return null;
}
}
//方式二
public static Car getAudi(){
return new Audi();
}
public static Car getByd(){
return new BYD();
}
}
工厂方法模式
若要加新产品不需要修改原有代码,仅需添加一个工厂类和车辆类即可,但是工厂的具体角色写死了
interface Car{
void run();
}
class Audi implements Car{
@Override
public void run() {
System.out.println("奥迪run");
}
}
class BYD implements Car{
@Override
public void run() {
System.out.println("比亚迪run");
}
}
interface CarFactory{
Car getCar();
}
class AudiFactory implements CarFactory{
@Override
public Car getCar() {
return new Audi();
}
}
class BydFactory implements CarFactory{
@Override
public Car getCar() {
return new BYD();
}
}
抽象工厂模式
与工厂模式的区别在于需要创建对象的复杂程度
静态(static)
可以用来修饰属性、方法、代码块、内部类。
修饰属性:静态变量(类变量)
- 按是否使用static修饰,又分为静态属性v.s.非静态属性(实例变量)
- 实例变量:创建了类的多个对象,每个对象独立拥有一套类的非静态属性
- 静态变量:多个对象共享一个静态变量
- 静态变量随着类的加载而加载(早于对象的创建)
- 类只会加载一次,静态变量在内存中只会存在一份:在方法区的静态域中
- 举例:System.out、Math.PI
修饰方法:静态方法
- 静态方法不能重写
- 静态方法中只能调用静态的方法/属性
- 非静态方法中既可以调用静态方法/属性,也已调用非静态的方法/属性
- 在静态的方法内,不能使用this、super关键字
设计模式:单例(Singleton)
设置某个类只能存在一个对象实例
- 构造器访问权限设为private,因此不能在类的外部new出类的对象
- 调用该类的静态方法返回类内部创建的对象
- 静态方法只能访问静态变量,因此指向类内部产生的该类对象的变量也应该是静态的
饿汉式
class Bank{
//1.私有化类的构造器
private Bank(){
}
//2.内部创建类的对象
//4.要求此对象也必须为static的
private static Bank instance=new Bank();
//3.提供公共方法返回类的对象
public static Bank getInstance(){
return instance;
}
}
优:线程安全
劣:对象加载时间过长
懒汉式
class Bank{
//1.私有化类的构造器
private Bank(){
}
//2.声明当前类对象
//4.此对象也必须为static的
private static Bank instance=null;
//3.声明public、static的返回当前类对象的方法
public static Bank getInstance(){
if(instance==null){
instance=new Bank();
}
return instance;
}
}
优:延迟对象创建
劣:线程不安全,需要加锁
方式一:效率稍差
public static Bank getInstance(){
synchronized (Bank.class){
if(instance==null){
instance=new Bank();
}
return instance;
}
}
方式二:效率稍高
public static Bank getInstance(){
if(instance==null){
synchronized (Bank.class){
if(instance==null){
instance=new Bank();
}
}
}
return instance;
}
this
可以用来修饰属性、方法、构造器。理解为:当前对象
class Person{
int age;
String name;
Person(){
System.out.println("空构造器");
}
Person(int age){
this();//调用空构造器
System.out.println("带age的构造器");
}
Person(String name,int age){
this(age);//调用带age的构造器
System.out.println("带name和age的构造器");
}
}
this(形参列表)必须声明在当前构造器的首行
构造器内部最多只能用一个this(形参列表)来调用其他构造器
super
显式调用父类中声明的属性或方法
属性和方法:当子类和父类中定义了同名的属性/方法,想要在子类中调用父类声明的属性/方法,必须显式使用“super.属性/方法”
构造器:
- 必须在子类构造器的首行,this(形参列表)和super(形参列表)只能二选一
- 当构造器首行没有显式声明this(形参列表)或super(形参列表),则默认调用父类空参构造器,也就是super()。
final
可以修饰类、方法、变量
- 修饰类:此类不能被其他类锁继承 如:String类、System类、StringBuffer类
- 修饰方法:此方法不能被重写 如:Object类中的getClass()
- 修饰变量:常量
- 修饰属性:可以赋值的位置有:显式初始化、代码块中初始化、构造器中初始化
- 修饰局部变量:尤其是使用final修饰形参时,表明此形参是常量。调用此方法时,给常量形参赋一个实参,一旦赋值无法修改。
- static final用来修饰属性:全局常量
package
为了更好的实现项目中类的管理,提供包的概念
使用package申明类或接口所属的包,声明在源文件的首行
包属于标识符,命名规范xxxyyyzzz
每”.”一次,代表一层文件目录