一单例
意义: Java中一种设计模式
核心思想:
在程序运行当中该类的对象不管怎么创建,始终保持有且只有一个该类的对象.
编写思路:
1.不让外界创建对象(私有化构造方法)
2.在该类的内部创建这个对象(让这个对象只创建一次)
3.给类外部 提供一个获取该对象的方法(相当于提供一个get方法)
下面看两种单例类似型
饿汉式:在类初始化时,已经自行实例化
class SingleE{
// 私有化构造方法
private SingleE(){}
//声明一个本类的对象
private static SingleE SINGLE = new SingleE();
//对外提供一个访问的方法 (返回本类的对象)
public static SingleE getInstance(){
return SINGLE;
}
}
懒汉式:(在第一次调用的时候实例化自己 )延迟加载
class Singlazybones {
// 私有化构造方法
private Singlazybones() {}
private static Singlazybones singlazybones = null;
public static Singlazybones getInstance() {
// 当这个对象不存在时 再创建
if (singlazybones==null) {
singlazybones = new Singlazybones();
}
return singlazybones;
}
}
二 抽象类
意义:
在面向对象的概念中,所有的对象都是通过类来描绘的,但是反过来,并不是所有的类都是用来描绘对象的,如果一个类中没有包含足够的信息来描绘一个具体的对象,这样的类就是抽象类.
关键词:
abstract
可以修饰类 该类就是抽象类,
修饰方法 抽象方法
注意问题:
1.有抽象方法的类一定是抽象类
2.抽象类中不一定有抽象方法
3.抽象类不能直接创建对象.
4.强制子类重写父类的抽象方法
5.使用多态的方式进行创建
核心:
抽象类不能直接使用,只能使用抽象类的子类.
抽象类中可以有哪些内容:
1.变量和常量
2.构造方法
3.抽象方法和成员方法
关键词不能和哪些关键词共存
1.final 修饰抽象方法 不能被重写
2.private 修饰抽象本类方法 只能本类访问
3.static 修饰的方法使用类名调用 ,抽象方法没有实现部分,不能直接调用
看一个例子
/* BiXieJP
* YBQ
* LPZ
* 武林上盛传了一部 辟邪剑谱(第一式 自宫)
* 该剑谱 被 岳不群与林平之 习得
* 岳不群 笑着用剑自宫
* 林平之 用锤子自宫
*/
public class Demo03 {
public static void main(String[] args) {
BiXieJP zg1= new YBQ();
zg1.fun();
BiXieJP zg2= new LPZ();
zg2.fun();
}
}
abstract class BiXieJP{
public abstract void fun() ;
}
class YBQ extends BiXieJP{
@Override
public void fun() {
System.out.println("岳不群 "
+"宁教我负天下人,不叫天下人负我"
+ "笑着用剑自宫");
}
}
class LPZ extends BiXieJP{
@Override
public void fun() {
System.out.println("林平之眼含泪水, 用锤子自宫");
}
}
三 模板设计模式
使用情况:
大部分内容一样,只需要修改一部分.
模式中的角色
抽象类(AbstractClass):实现了模板方法,定义了算法的骨架。
具体类(ConcreteClass):实现抽象类中的抽象方法,已完成完整的算法。
模板方法模式的用意:
准备一个抽象类,将部分逻辑以具体方法以及具体构造函数的形式实现,声明一些抽象方法来迫使子类实现剩余的逻辑。不同的子类可以以不同的方式实现这些抽象方法,从而对剩余的逻辑有不同的实现。
public class Demo01 {
public static void main(String[] args) {
LOStudy lsk = new LSK();
lsk.study();
}
}
abstract class LOStudy{
// 学习方法
public void study() {
System.out.println("报名缴费");
//学科选择是不同的
//调用抽象方法
chooseSubject();
System.out.println("毕业找工作");
}
//学科选择是不同的 声明一个抽象方法
public abstract void chooseSubject() ;
}
class LSK extends LOStudy{
//重写抽象方法
@Override
public void chooseSubject() {
System.out.println("学Java");
}
}
class PQ extends LOStudy{
//重写抽象方法
@Override
public void chooseSubject() {
System.out.println("学 H5");
}
}
在上面的例子中study 方法是一个模板 其中只有学习学科的内容不同其他大部分都一样.而不同的子类重写父类的抽象方法有不同的表现.
四 接口
意义:
在JAVA编程语言中是一个抽象类型,是抽象方法的集合,接口通常以interface来声明。一个类通过继承接口的方式,从而来继承接口的抽象方法.
广义: 相当于一个规则 规范 是需要来遵守;
接口中的一些主要注意问题:
1.可以声明抽象方法,不能声明成员方法;
2.可以声明变量,但是变量默认被 final static修饰无法修改;
3.声明抽象方法时 默认被 public abstract 修饰(可以省略);
4.接口只能用来实现,不能被继承;
5.接口和类都一样会翻译成.class文件被执行.
6.接口中没有构造方法,用的是实现不是继承.
看一个例子
public class Demo03 {
public static void main(String[] args) {
//创建接口 使用多态的形势创建
InterA a = new InterAImpl();
a.fun();
System.out.println(InterA.num);
}
}
// 声明一个接口
interface InterA{
int num =10;
public abstract void fun();
}
//接口的实现类 类名的一般都以Impl 结尾
//接口使用implements 关键词实现
class InterAImpl implements InterA{
// 实现接口中的 抽象方法
@Override
public void fun() {
//num = 15; //会报错,值不能修改
System.out.println(num);
System.out.println("我是实现类的 fun 方法");
}
}
打印结果
10
我是实现类的 fun 方法
10
类与接口之间的关系
类与类之间 只允许单继承(亲爹的关系)
接口和类 实现的关系 可以多实现(干爹的关系)
接口和接口 可以单继承也可以多继承
抽象类与接口的区别:
类:
抽象类是用来捕捉子类的通用特性的 。
它不能被实例化,只能被用作子类的超类。
抽象类是被用来创建继承层级里子类的模板
接口:
接口是抽象方法的集合。如果一个类实现了某个接口,那么它就继承了这个接口的抽象方法。
这就像契约模式,如果实现了这个接口,那么就必须确保使用这些方法。
接口只是一种形式,接口自身不能做任何事情。
1.实现
抽象类: 继承
接口:实现(implememnts)
2.成员变量
抽象类: 常量 变量
接口:只能是常量
3.成员方法
抽象类: 可以是抽象方法 也可以是成员方法
接口:只能是抽象方法(静态方法 和 默认方法)
构造方法
抽象类: 有构造方法
接口:没有构造方法
public class Demo04 {
public static void main(String[] args) {
Animal gf = new GarfieldImpl();
gf.cry();
gf.eat();
//向下转型
GarfieldImpl garfieldImpl =(GarfieldImpl)gf;
garfieldImpl.jump();
}
}
// 动物类
abstract class Animal{//抽象类
public abstract void eat();
public abstract void cry();
}
//猫的接口
interface jump{
public abstract void jump();
}
class Cat extends Animal{
// 重写吃的抽象方法
@Override
public void eat() {
System.out.println("我吃猫粮");
}
//重写叫的抽象方法
@Override
public void cry() {
System.out.println("我会喵喵叫");
}
}
class GarfieldImpl extends Cat implements jump{
@Override
public void jump() {
System.out.println("我能站起来跳高");
}
}
// 接口与接口之间的关系
interface InterD{
public abstract void fun3();
}
interface InterE{
public abstract void fun4();
}
interface INterF extends InterD,InterE{
}
class InterFImpl implements INterF{
@Override
public void fun3() {
// TODO Auto-generated method stub
}
@Override
public void fun4() {
// TODO Auto-generated method stub
}
}
补充: JDK1.8后的新特性
接口中扩充了静态方法 和 默认方法
public class Demo06 {
public static void main(String[] args) {
//调用接口中的静态方法
InterX.staticfun();
//调用接口中的默认方法
InterX X = new InterXImpl();
X.defaultfun();
// 调用实现类中的静态方法
InterXImpl.staticfun();
//调用实现类的特有方法
InterXImpl xImpl = (InterXImpl)X;
xImpl.print();
}
}
interface InterX{
//抽象方法
public abstract void fun();
// 默认方法 default
//不是必须在实现类中 重写
public default void defaultfun() {
System.out.println("我是接口中的默认方法");
}
//静态方法
public static void staticfun(){
System.out.println("我是接口中的静态方法");
}
}
class InterXImpl implements InterX{
// 实现接口中的抽象方法
@Override
public void fun() {
System.out.println("我是实现类中的 fun方法");
}
//重写默认方法
@Override
public void defaultfun() {
// 调用父类中的 默认方法
// 接口名 .super.默认方法名
InterX.super.defaultfun();
System.out.println("我是实现类中 defaultfun方法");
}
//实现类中自己的静态方法
public static void staticfun(){
System.out.println("我是实现类的静态方法");
}
//自己方法中是否可以调用父类的默认方法
public void print() {
InterX.super.defaultfun();
System.out.println("我是打印方法");
}
}