JAVA知识总结(四):单例模式和多态
好吧,今天一定要把面向对象的最后一个特性:多态,给说完。不过我们先来聊一聊设计模式,因为它很重要。
设计模式
官方的解释是,设计模式是:一套被反复使用,多数人知晓的,经过分类编目,代码设计经验的总结。说人话就是:软件开发人员在软件开发过程中面临的一般问题的解决方案。
常见的设计模式可以参看这张图片:
我们可以对其按照作用来进行分类::
关注对象创建过程的:创建型模式;
类和对象组合:结构型模式;
对象之间的通信过程:行为型模式;
单例模式
单例模式: 一个类有且仅有一个实例,并且自行实例化向整个系统提供,它的目的就是使得类的一个对象成为该类系统中的唯一实例。
要点:
- 某个类只能有一个实例;;
- 必须自行创建实例;
- 必须自行向整个系统提供这个实例;
实现:
1、只提供私有的构造方法;
2、只含有一个该类的静态私有对象;
3、提供一个静态的公有方法用于创建、获取静态私有对象。
对于1的理解:private是访问限制能力最强的修饰符,只能在当前类内被使用。也就是说经过private修饰,该类的对象在类外无法通过new关键字直接实例化,这样可以做到限制类实例化产生;
对于2的理解:1可以实现有且仅有一个实例,static修饰的静态成员可以满足该类有且仅有一个,所有的对象都共享这一个静态成员;
对于3的理解:类似于封装,必须向外部系统提供唯一的公有访问方法。
在java中实现单例模式有2种方式:饿汉式和懒汉式。
饿汉式:在类中私有对象创建的过程中立刻进行实例化操作(言外之意,不管你用不用,我先把这个给做了)如此看来确实挺饿的;
懒汉式::对象创建时并不立刻进行实例化操作,而是在静态公有方法中进行实例化操作(言外之意,你不需要我就不做)如此看来确实挺懒的。
饿汉式
饿汉式:在类中私有对象创建的过程中立刻进行实例化操作(言外之意,不管你用不用,我先把这个给做了):
package SingleExample;
// 饿汉式:创建对象实例的时候直接初始化;(空间换时间)
public class SingletonOne {
//1、创建类中私有的构造方法
private SingletonOne() {
};
//2、创建该类型的私有静态实例
private static SingletonOne instance = new SingletonOne();
//3、创建公有的静态方法,返回静态实例对象
public static SingletonOne getinstance() {
return instance;
};
}
测试代码:
package SingleExample;
public class SingleOneTest {
public static void main(String[] args) {
// TODO Auto-generated method stub
SingletonOne one =SingletonOne.getinstance();
SingletonOne two =SingletonOne.getinstance();
System.out.println(one==two); //输出结果为true
}
}
懒汉式
懒汉式::对象创建时并不立刻进行实例化操作,而是在静态公有方法中进行实例化操作(言外之意,你不需要我就不做):
package SingleExample;
//懒汉式:创建对象实例的时候并不初始化;(时间换空间)
public class SingletonTwo {
// 1、创建类中私有的构造方法
private SingletonTwo() {
};
// 2、创建静态的该类实例对象
private static SingletonTwo instance = null;
// 3、创建公有的静态方法,提供实例对象
public static SingletonTwo getinstance() {
if (instance == null) {
instance = new SingletonTwo();
}
return instance;
};
}
相应的测试代码为:
package SingleExample;
public class SingleTwoTest {
public static void main(String[] args) {
// TODO Auto-generated method stub
SingletonTwo one = SingletonTwo.getinstance();
SingletonTwo two = SingletonTwo.getinstance();
System.out.println(one == two); //输出结果为true
}
}
单例模式两种实现总结
饿汉式在类加载时就创建实例,第一次加载速度快;
懒汉式在第一次使用时才进行实例化,第一次加载速度慢;
饿汉式:空间换时间
懒汉式:时间换空间
饿汉式,类在加载时进行了对象的实例化创建,即使多个进程进行并发操作,访问的实例也是唯一的,饿汉式线程安全。
懒汉式,第一次使用才会实例化,多个线程并发操作时,由于时间片的切换,可能导致线程风险。
但是懒汉式的线程危险是可以规避的,通过关键字Synchronized实现线程的锁定,也可以通过静态内部类和枚举保证操作时的线程唯一。
单例模式优缺点及使用场景
单例模式的优点:
1、在内存中只有一个对象,节省内存空间;
2、避免频繁的创建销毁对象, 提高性能;
3、避免对共享资源的多重占用。
单例模式的缺点:
1、扩展比较困难;
2、如果实例化后的对象长期不利用,系统将默认为垃圾进行回收,造成对象状态丢失。
使用场景:
1、创建对象时占用资源过多,但同时又需要用到该类对象;
2、对系统内资源要求统一读写,如读写配置信息;
3、当多个实例存在可能引起程序逻辑错误,如号码生成器;
每一种设计模式都是针对场景,针对某种具体问题的,具体场景应当进行具体分析,选用合适的设计模式。
多态
终于开始进入多态的世界了,在这里你将全面了解多态的特点及使用。
多态你可以理解为不同类的对象对同一消息做出不同的响应。
一般而言,多态分为编译时多态和运行时多态这两种。
编译时多态:也称设计时多态,它是通过方法重载来实现的,编译器在编译状态可以进行不同行为的区分。
而运行时多态,则必须要求程序运行时,动态决定调用哪个方法。
我们通常在Java中的多态指的就是运行时多态。
实现多态的必要条件: 满足继承和重写;父类引用指向子类对象
向上转型
所谓的向上转型也指隐式转型(自动转型)。说通俗一点就是父类引用指向子类实例,它可以调用子类重写父类的方法以及父类派生的方法,但是无法调用子类特有方法。
举个例子,假如Dog这个类继承了我们Animal这个类,我们不仅可以这样:
Dog dog =new Dog();
Animal animal =new Animal();
你还可以这样:
Animal dog2 =new Dog();
这就是将一个子类对象转型为一个父类对象,这个很好理解,对吧。
接下来我们来说一下,向下转型,顾名思义就是和向上转型相反的操作了,是的,你很聪明。
向下转型
向下转型也称强制类型转换。它是子类引用指向父类实例,我们在之前就用过了,还记得我们在重写Object类的equals方法时,就将父类Object强制转换,然后才调用子类特有的方法。
向下转型并不是可以随便转换的,需要满足一定的转换条件。我们可以通过instanceof这个运算符来判断是否能进行强制类型转换。
通过上面的图片,我们可以很清楚的知道instanceof的作用就是判断左边对象是否是右边这个类的实例,如果是就返true,否则就返回false。
因此,我们在进行向下转型的时候,可以用instanceof来判断一个对象是否满足某个类的实例特征。满足,我们才进行类型转换,否则强制转换会报错。
总结一下:
向上转型: 父类引用指向子类对象。即小变大。
向下转型: 子类引用指向父类对象。即大变小。
需要注意的是:父类中static修饰的方法允许被子类使用,但是不允许被子类重写,所以向上转型之后,只能调用到父类原有的静态方法。如果此时要用子类中的,只能通过向下转型来实现。
抽象类
某个父类只是知道其子类应该包含怎样的方法,但无法准确知道这些子类如何实现这些方法,这样我们的抽象类就派上用场了。
抽象类可以避免子类设计的随意性,还可以避免父类无意义的实例化。
你只需知道,修饰抽象类要用abstract这个关键词,抽象类不可以直接被实例化。
抽象方法
我们前面说过,父类只是规定子类拥有该项能力,但在父类中具体实现它是没有任何意义的,因此该方法应设置为抽象方法。
public abstract void test();
你记住,抽象方法是不允许有方法体的,也就是不能有花括号。而且此时子类必须实现父类的抽象方法,如果你不实现,那么这个类就必须被设置为抽象类(不设置就会报错),然后由继承它的类去具体实现相应的方法。简单来说就是一句话:抽象方法中不允许包含方法体,子类需要重写父类的抽象方法。
一般抽象类适用于这种情况:1、父类中的实现没有意义;2、提醒子类必须要去自己实现自己的这个方法。
通常子类变多了之后,你新建一个类只要继承了抽象的父类,IDE会自动提醒你实现父类中的抽象方法的,你不实现就会报错。
抽象类和抽象方法的使用
你可以使用abstract关键词来定义抽象类,抽象类不能被直接实例化,你可以通过向上转型完成对象实例,只能被继承。
abstract关键词定义抽象方法 ,你不需要具体实现也不能具体实现,也就是花括号不能有。
需要注意的是:抽象类可以没有抽象方法,但包含抽象方法的类一定是抽象类。
我们前面说过,当一个类继承抽象类,必须实现类中的抽象方法。如果不重写,则必须将该子类也变为抽象类,由其子类来实现,否则会报错。
注意:static final private 不可以和abstract同时出现(因为抽象方法是要在子类中进行重写的,而private只能在当前类被访问,final方法不允许被子类重写,static静态不允许被子类重写。)
JAVA知识总结(四):单例模式和多态的更多相关文章
- 测试必备之Java知识(四)—— 线程相关
线程相关 Java多线程实现方式 继承Thread,实现Runnable接口,实现Callable接口(能抛异常且有返回值,不常用) 为什么有了继承Thread方式还要有Runnable接口方式 实现 ...
- “全栈2019”Java第五十四章:多态详解
难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java第 ...
- 实现网络数据提取你需要哪些java知识
本篇对一些常用的java知识做一个整合,三大特性.IO操作.线程处理.类集处理,目的在于能用这些只是实现一个网页爬虫的功能. Ⅰ 首先对于一个java开发的项目有一个整体性的了解认知,项目开发流程: ...
- Android开发学习必备的java知识
Android开发学习必备的java知识本讲内容:对象.标识符.关键字.变量.常量.字面值.基本数据类型.整数.浮点数.布尔型.字符型.赋值.注释 Java作为一门语言,必然有他的语法规则.学习编程语 ...
- JAVA之旅(八)——多态的体现,前提,好处,应用,转型,instanceof,多态中成员变量的特点,多态的案例
JAVA之旅(八)--多态的体现,前提,好处,应用,转型,instanceof,多态中成员变量的特点,多态的案例 学习是不能停止的 一.多态 我们今天又要学习一个新的概念了,就是多态,它是面向对象的第 ...
- Java多线程核心技术(五)单例模式与多线程
本文只需要考虑一件事:如何使单例模式遇到多线程是安全的.正确的 1.立即加载 / "饿汉模式" 什么是立即加载?立即加载就是使用类的时候已经将对象创建完毕,常见的实现办法就是直接 ...
- Java知识回顾 (1) 编译环境与基本变量类型
参考资料 runoob Java知识回顾序列的相关资料,主要来自 runoob,并对其中的知识进行概况或总结,去除对一个之前了解过Java的人员无关的知识点.以便能够使得一个新手,或之前有Java经验 ...
- Java知识集锦
Java知识集锦 一.Java程序基础 1.1 开发和运行环境 1.2 Java语言概述 二.Java语法基础 2.1 基础类型和语法 2.2 对象和类型 2.3 包和访问控制 三.数据类型及类型转换 ...
- 七:Java之封装、抽象、多态和继承
本文章介绍了关于Java中的面向对象封装.抽象.继承.多态特点 Java面向对象主要有四大特性:封装.抽象.继承和多态. 一.封装 封装就是将抽象得到的数据和行为(或功能)相结合,形成一个有机的总体, ...
- developerWorks 中国 技术主题 Java technology 文档库 Java 性能测试的四项原则
转-https://www.ibm.com/developerworks/cn/java/j-lo-java-performance-testing/?cm_mmc=dwchina-_-homepa ...
随机推荐
- Python 变量详解[学习 Python 必备基础知识][看此一篇就够了]
您的"关注"和"点赞",是信任,是认可,是支持,是动力...... 如意见相佐,可留言. 本人必将竭尽全力试图做到准确和全面,终其一生进行修改补充更新. 目录 ...
- E - Dividing Chocolate ATcoder
题目大意:切割图形,给你一个非0即1的矩阵,将它切割成多个长方形,使每个小长方形中1的个数不得多于k个,切割的规则,要么切一整行,要么是一整列. 题解: 二进制枚举. 注意行数最大才是10.用二进制枚 ...
- 判断一个字符串是否是合法IP地址
# -*- coding: utf-8 -*- """ @File:test06_判断ip地址是否合法.py @E-mail:364942727@qq.com @Time ...
- Upload-Labs 实验操作记录
0x01 安装 下载:https://github.com/c0ny1/upload-labs 环境:简单搭建phpstudy环境即可,记得在upload-labs根目录下创建该文件夹 0x02 文件 ...
- 【学习笔记】splay入门(更新中)
声明:本博客所有随笔都参照了网络资料或其他博客,仅为博主想加深理解而写,如有疑问欢迎与博主讨论✧。٩(ˊᗜˋ)و✧*。 前言 终于学习了 spaly \(splay\) !听说了很久,因为dalao总 ...
- 改善 Python 程序的 91 个建议
1.引论 建议1:理解Pythonic概念—-详见Python中的<Python之禅> 建议2:编写Pythonic代码 避免不规范代码,比如只用大小写区分变量.使用容易混淆的变量名.害怕 ...
- web前端该怎么入门?web前端入门教程(非常详细)
初学编程的小伙伴经常会遇到的问题,1.没资源 2.没人带 3.不知道从何开始 ,小编也是从新手期过来的,所以很能理解萌新的难处,现在整理一些以前自己学习的一些资料送给大家,希望对广大初学小伙伴有帮助! ...
- NGINX反向代理,后端服务器获取真实IP
一般使用中间件做一个反向代理后,后端的web服务器是无法获取到真实的IP地址. 但是生产上,这又是不允许的,那么怎么解决? 1.在NGINX反向代理服务器上进行修改 2.修改后端web服务器配置文件 ...
- [Inno Setup] 卸载 重启之后 删除文件
某些系统文件,例如驱动,不重启无法删除. 利用windows注册表里的 RunOnce.注意必须在HKLM下,否则可能权限不够. 不能直接填cmd命令,要以cmd的参数形式填写. procedure ...
- [Qt] 文本文件读写, 摘自官方文档
Reading Files Directly The following example reads a text file line by line: QFile file("in.txt ...