OOP
面向对象的三大特征:封装,继承,多态。
封装
将客观客观事物封装成一个抽象的类,将其属性与方法组合在一起,并且类可以把自己的数据和方法只让可信的类或者对象操作,对不可信的隐藏其具体实现。
继承
通过扩展一个现有类建立一个新类,这个扩展后的新类具有被扩展类的所有属性和方法(处隐藏了的外)。通过继承创建的新类称为“子类”或者“派生类”,被继承的类称为“父类”或者"超类"。
多态
一个实体的多种形态,是允许将父对象设置为可以和他的子对象相等的技术,赋值之后父对象可以根据当前赋值给他的子对象的特征以不同的方式运作。就是允许将子类类型的指针赋值给父类类型的指针;
实现多态的方式有覆盖(重写)和重载:
覆盖(重写):子类重新定义父类的虚函数;
重载:允许存在多个同名函数,而这些函数的参数列表不同(参数个数或者参数类型)
增强软件的灵活性和重用性
1.1类和对象
类是Java语言中最基本的单位,是一类事务的抽象,类里有方法和属性。
对象是具体的实例。
package Review;
import com.sun.security.auth.UnixNumericGroupPrincipal;
public class CreatObjectAndClass {
public static void main(String[] args) {
//实例化一个对象 student
Student student1=new Student() ;
System.out.println(student1.name);
System.out.println("number="+student1.number);
student1.Age(16);
student1.SumScore(98,76);
//实例化多个对象
Student student2=new Student() ;
student2.SumScore(22,44);
}
}
//创建一个类
class Student{
//属性
String name;
int age;
int number=22;
int math;
int english;
//无参方法
public void study(){
System.out.println("学习");
}
//含参方法
public void Age(int age){
System.out.println("今年"+age+"岁");
}
//返回值方法
public int SumScore(int math,int english){
return math+english;
}
}
对象的三个特点:
行为:可以对对象完成哪些操作,或者对对象应用哪些方法;
状态:当调用那些方法时,对象会如何响应;
标识:区分具有相同行为和状态的不同对象;
通过class关键字创建类,通过new创建对象;
创建对象的不同方式
1.可以通过new关键字调用。但是会增加耦合度。
Hello hello=new Hello();
2.可以使用Class类里的newInstance。
Class heroClass = Class.forName("yunche.test.Hello");
Hello h =(Hello) heroClass.newInstance();
h.sayWorld();
使用Constructor类的newInstance方法
//获取类对象
Class heroClass = Class.forName("yunche.test.Hello");
//获取构造器
Constructor constructor = heroClass.getConstructor();
Hello h =(Hello) constructor.newInstance();
h.sayWorld();
3.可以采用clone方式,对已经分配了内存的源对象进行clone,但是要想使用clone方法实现Cloneable接口。
public class Hello implements Cloneable
{
public void sayWorld()
{
System.out.println("Hello world!");
}
public static void main(String[] args)
{
Hello h1 = new Hello();
try
{
Hello h2 = (Hello)h1.clone();
h2.sayWorld();
}
catch (CloneNotSupportedException e)
{
e.printStackTrace();
}
}
}
4.采用序列化机制,使用序列化时,要实现实现Serializable接口,将一个对象序列化到磁盘上,而采用反序列化可以将磁盘上的对象信息转化到内存中。
public class Serialize
{
public static void main(String[] args)
{
Hello h = new Hello();
//准备一个文件用于存储该对象的信息
File f = new File("hello.obj");
try(FileOutputStream fos = new FileOutputStream(f);
ObjectOutputStream oos = new ObjectOutputStream(fos);
FileInputStream fis = new FileInputStream(f);
ObjectInputStream ois = new ObjectInputStream(fis)
)
{
//序列化对象,写入到磁盘中
oos.writeObject(h);
//反序列化对象
Hello newHello = (Hello)ois.readObject();
//测试方法
newHello.sayWorld();
}
catch (FileNotFoundException e)
{
e.printStackTrace();
}
catch (IOException e)
{
e.printStackTrace();
}
catch (ClassNotFoundException e)
{
e.printStackTrace();
}
}
}
匿名对象
没有名字的对象,是对象的简化表示形式。当被调用的对象值调用一次时使用。
//创建了一个匿名对象并调用其方法
new Demo().shoe();
1.2封装
隐藏对象的属性和实现细节,提高安全性和重用性。
private 权限修饰符进行封装,既可以封装类也可以封装方法,封装后的类和方法不能直接被外调用,只能在本类中调用。但是可以间接调用,提供公开的方法,如get()和set()。
Java中的四种权限修饰符:
public(公共的,最大权限,任何地方可访问)
protected(保护的,只能在同一个包或者其本类及子类访问)
default(可以不写,程序默认情况,本类和同包类,子类不能访问)
private(私有的,只有本类可以访问)。

package ClassAndObject;
public class CreatPrivate {
public static void main(String[] args) {
//实例化一个对象
Studen studen=new Studen();
//封装类里的属性不能被其对象直接访问
//System.out.println(student.name);
//封装类里的方法也不能被直接访问
//student。study();
//对象可以调用类的公共方法,从而间接调用其封装方法
studen.Study();
//用set()和get()间接调用封装属性
studen.setname("Bob");
System.out.println(studen.getname());
}
}
class Studen{
//封装属性name
private String name="Alica";
//封装方法study()
private void study() {
System.out.println("学习封装方法");
}
public void Study() {
//类本身可以调用其自身的封装方法
study();
}
public void setname(String Name) {
name=Name;
}
public String getname() {
return name;
}
}
构造方法
构造方法是一个与类同名且返回值类型为同名类类型的方法。对象的创建是通过构造方法来完成的,其主要功能是完成对象的创建或者对象的实例化。当实例化一个对象时会自动调用一个构造方法。
构造方法的参数可有可无。构造方法也可以重载。构造方法不能被子类继承,所以没法重写。但是可以重载。
如果不写构造方法,默认创建无参构造方法。要想使无参构造方法失效,可以重载含参构造方法。
格式
//可无参也可以有参
修饰符 类名(【参数】){
代码……
}
构造方法创建对象并赋值
package ClassAndObject;
public class CreatNewMethod {
public static void main(String[] args) {
//a是引用变量,引用的是对象的地址值。无参函数创建的对象
Stu a=new Stu();
//含参函数创建的对象
Stu b=new Stu(1);
b.setB(12);
System.out.println(b.getB());
}
}
class Stu{
int a;
int b;
//无参构造函数
public Stu() {
System.out.println("这里是无参构造函数");
}
public Stu(int a) {
//含参构造方法初始化赋值
this.a=a;
System.out.println("这里是"+a+"个含参构造函数");
}
//赋值方法2
public int getB() {
return b;
}
public void setB(int b) {
this.b = b;
}
}
构造代码块
在类的内部,方法外部,的代码块。常用于抽取构造方法中的共性代码。 每次调用构造方法前都会调用构造代码块, 优先于构造方法加载。
package NewMethod;
public class NewCodeBlock {
public static void main(String[] args) {
Teacher t=new Teacher();
}
}
class Teacher{
//构造代码块
{
System.out.println("构造代码块");
}
public Teacher(){
System.out.println("g构造方法");
}
}
//输出结果:
//构造代码块
//g构造方法
this
局部变量的值赋值给成员变量时,若局部变量和成员变量同名,用代表本类的对象this来完成。this可以看作本类对象的一个引用对象。
package NewMethod;
public class ThisNewMethod {
public static void main(String[] args) {
Teache tea=new Teache();
}
}
class Teache{
int age;
public Teache() {
//this(13);//this(13)调用含参构造函数必须放在第一行
System.out.println("无参构造函数");
//this(12);
}
public Teache(int age) {
this();//调用无参构造函数。但是不同同时调用。this()和this(13)不能同时使用
this.age=age;
System.out.println("含参构造函数"+age);
}
}
1.3继承
类得继承
继承是从已有的类中派生出新的类。派生出得类可以使用父类得属性和方法,除private外。
用extends定义,java支持单继承。
package ClassAndObject;
public class SonAndFather {
public static void main(String[] args) {
//static方法里面只能调用static属性或者方法
onn X=new onn();//子类对象
onn.worki();//子类方法
System.out.println(onn.age);
}
}
//父类
class father{
public static int age;
public static String name;
public static void worki() {
System.out.println("工作");
}
}
//子类
class onn extends father{
int score;
public static void studying(){
System.out.println("学习");
}
}
super
过super关键字可以使用父类的内容,可以看作父类的一个引用对象,如果用,必须出现在调用位置的第一行。
package ClassAndObject;
public class UseSuper {
public static void main(String[] args) {
soo xixi=new soo(33);//自动匹配无参构造
System.out.println(xixi.ag);
}
}
class fa{
public int ag;
public fa() {
}
public static void as(){
System.out.println("");
}
}
class soo extends fa{
//子类得构造方法,会自动调用super();
public soo(int ag) {
super();//自动调用隐藏了得super()方法,super()是父类得无参构造方法;必须放在第一条语句
super.ag=ag;
}
}
方法的重写
1、 继承后,子类就拥有了父类的功能
2、 那么在子类中,可以添加子类特有的功能也可以修改父类的原有功能
3、 子类中方法签名与父类完全一样(包括方法的返回值,方法名和参数列表,完全一致时,会发生覆盖/复写操作,相当于修改功能
注意:
1、父类中的私有方法和构造方法不能被重写
2、子类重写父类方法时,修饰符要大于等于父类修饰符的权限
package ClassAndObject;
public class Overide {
public static void main(String[] args) {
erzi E=new erzi();
//重写后的方法
E.method1(3);
//重写前得方法
E.method1();
}
}
class dady{
public void method1() {
System.out.println("dady");
}
}
class erzi extends dady{
//方法重写:子类中方法签名与父类完全一样(包括方法的返回值,方法名和参数列表,完全一致)
public void method1(int a) {
System.out.println(a);
}
}
继承中的构造方法
子类创建对象时,默认去访问父类的无参构造方法。
在构造方法的第一行,都有一条默认语句:super();
父类没有无参构造函数时,可以用super调用父类的其他构造函数。
this和super的区别
1.this代表本类对象的引用,super代表父类对象的引用。
2.this常用于区分局部变量和成员变量,super用于区分父类成员和本类成员。
3.this和super不可以同时出现在同一个构造方法里,他们只要出现都必须放在第一行,同时出现的话会矛盾。
重写和重载的区别
重载:是指同一个类中的多个方法具有想用的名字,饭这些方法具有不同的参数列表,即参数的数量或者参数类型不能完全相同。一个类中多态性的一种表现。
重写:是存在父子类之间的,子类定义的方法与父类的方法具有相同的方法名字,相同的参数列表和相同的返回类型,是子类与父类之间多态性的一种表现。
static
修饰成员变量和成员方法得关键字,只加载一次,会一直存在,不再开辟新空间,全局唯一,全局共享。随着类得加载而加载,优先于对象加载,可以直接被类名调用,静态只能调静态,非静态可以随意调用。static不能和this或super公用,因为有static时可能还没有对象。
package ClassAndObject;
public class SeeStatic {
public static void main(String[] args) {
System.out.println(fat.a);//可以先与创建对象前通过类名直接访问静态属性
s sa=new s();
sa.eat();
sa.sleep();
}
}
class fat{
public static int a=99;
public int b=98;
public void eat() {//非静态都可以访问
System.out.println(b);
System.out.println(a);
}
public static void sleep() {
//System.out.println(b);静态方法不能访问非静态
System.out.println(a);//非静态可以访问非静态
}
}
class s extends fat{
// public void eat() {
// System.out.println("eat");
// }
//若子类里没有匹配得方法则去父类方法里寻找
}
静态变量和实例变量
静态变量前要加static关键字,实例变量不用;
实例变量属于某个实例对象的属性,必须创建了实例对象,其中的实例变量次啊会分配空间,才能使用这个实例变量。静态变量不属于某个实例,而是属于类,所以也称为类变量,只要程序加载了类的字节码,不用创建人任何实例对象,静态变量就会被分配空间,静态变量就可以被使用。
静态代码块
随着类的加载而加载,并且只被加载一次,一般用于项目的初始化
static{…}
代码块
1.普通代码块:类中方法的方法体
2.构造代码块:构造代码块会在创建对象时被调用,每次创建时都会被调用,优先于类构造函数执行。构造代码块在创建对象时被调用,每次创建对象都会被调用,并且构造代码块的执行次序优先于类构造函数,如果出现多个构造代码块,执行顺序有他们在代码中出现的次序决定,先出现先执行。
3.静态代码块:用static{}包裹起来的代码块,静态代码块优先于构造代码块执行。只在第一次new时执行一次,之后不在执行。静态代码块不能直接访问实例变量和实例方法,需要通过类的实例对象来访问。
4.同步代码块:使用synchronized(){}包裹起来的代码块,在多线程环境下,对共享数据的读写操作时需要互斥进行的,否则会导致数据的不一致性。同步代码块需要卸载方法中。
执行顺序: 静态 - 构造代码块 - 构造方法 - 局部
final
被final修饰的类不能被继承;
被final修饰的方法不能被重写,可以被重载;
被final修饰的变量为常量,不可以被更改;
final 数据类型 常量名=值;
子类可以通过继承修改父类,如果父类不想被修改可以是fina修饰。
1.8多态
多态是指同一个实体具有多种形式。主要指同一个对象,在不同时刻代表的对象不一样,值得是对象的多种形态。,可以把不同的子类对象都当作父类来看,可以屏蔽不同子类对象之间的差异,写出通用的代码。我们可以不用关系某个对象到底是什么具体类型,就可以使用该对象大的某些方法,提高了程序的扩展性和可维护性。
由小到大,向上转型
继承是为了在不修改源代码得基础上增加新功能设定;封装是为了保护代码;多态是为了提供统一调用标准。可以把不同得子类当成父类来看,子类得方法可以千遍万化,但是只能调用从父类重写过去得方法。所以多态得前提是继承,同时要有方法得重写。在多态中编译看左边,运行看右边。
package ClassAndObject;
public class ManyStation {
public static void main(String[] args) {
//创建多态
Dd Duo=new So();
//Duo.other();不能调用父类中没有得方法
Duo.eat();//子类重写后的方法
System.out.println(Duo.ans);//父类的属性。成员变量使用的是父类的
}
}
class Dd{
public int ans=99;
public void eat() {
System.out.println("父类eat()");
}
}
//多台得前提是继承
class So extends Dd{
public int ans=3;
public void other() {
System.out.println("非重写方法");
}
public void eat() {
System.out.println("子类方法重写");
}
}
由大到小,向下转型
向下转型(较少):子类的引用的指向子类对象,过程中必须要采取到强制转型。
Parent p = new Child();//向上转型,此时,p是Parent类型
Child c = (Child)p;//此时,把Parent类型的p转成小类型Child
//其实,相当于创建了一个子类对象一样,可以用父类的,也可以用自己的
说明:向下转型时,是为了方便使用子类的特殊方法,也就是说当子类方法做了功能拓展,就可以直接使用子类功能。
1.4 异常
异常的继承结构
Throwable-顶级父类
--Error:程序中无法处理的错误,一般标识运行时JVM出现问题。
--Exception:程序本身可以捕获并且可以处理的异常。
--RunTimeExcetion:运行时异常(不受检异常),JVM运行期间可能出现的错误,编译器不会检查此类异常,如数组下标越界,空指针异常等
--Other:受检异常,编译器会检查的异常,必须对该异常进行处理,否则编译不通过。
异常处理
抛出异常:
一个方法不处理这个异常,而是调用层次向上传递,谁调用这个方法,这个异常就由谁来处理。
throw:用在方法内,用来抛出一个异常对象,将这个异常对象传递到调用者出,并结束当前方法的执行。
public class DemoThrow {
public static void main(String[] args) {
int a = DemoThrow.div(4,0);
System.out.println(a);
}
public static int div(int a,int b)
{
if(b==0)
throw new ArithmeticException("异常信息:除数不能为0");//抛出具体问题,编译时不检测
return a/b;
}
}
throws:用于方法声明之上,用于标识当前方法不处理异常,而是提醒该方法的调用者来处理异常。
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
public class DemoThrows {
public static void main(String[] args) throws FileNotFoundException{
readFile();
}
public static void readFile() throws FileNotFoundException {
InputStream is = new FileInputStream("E:/iodemo/ch01.txt");
}
}
捕获异常
捕捉程序运行时的错误,封装起来不让用户看见。
try{
需要捕获的代码
}catch(异常类型 异常名){
处理方案
}
package ClassAndObject;
import java.util.InputMismatchException;
import java.util.Scanner;
public class useTry {
public static void main(String[] args) {
try {
int a=new Scanner(System.in).nextInt();
int b=new Scanner(System.in).nextInt();
System.out.println(a/b);
}
catch(InputMismatchException aaa) {
System.out.println("请输入整数");
}
catch(ArithmeticException e) {
System.out.println("除数不能为0");
}
catch(Exception aaa)
{
System.out.println("出现错误");
}
}
}
1.5抽象类
没有方法体的方法叫抽象方法,含有抽象方法的类叫抽象类(抽象类也可以不含有抽象方法),抽象类用abstract修饰。
抽象类可以被继承,但是不可以被实例化。可以有其他的非抽象方法。
一个类如果继承了抽象类,要么重写其父类的所有抽象方法,从而转化成普通类,只要还有抽象方法,就会是抽象类。
abstract class A{
public abstract void eat();
}
abstract与private,final,static矛盾,使用private私有化后子类无法被重写,static是静态的优先于对象存在,静态方法无法被重写,被final修饰后也无法被重写。
package ClassAndObject;
public class AbtractClass {
public static void main(String[] args) {
Fs xxi=new Fs();
//Fss xii=new Fss();抽象类不能被实例化
xxi.method2();
}
}
abstract class FF{
abstract public void method2() ;//
}
class Fs extends FF{
//继承抽象类需要重写所有抽象方法
public void method2() {
System.out.println("重写父类抽象方法");
}
}
abstract class Fss extends FF{
//可以增加其他的方法
public void method3() {
System.out.println("hahaha");
}
}
抽象类也有构造方法,但是本身不能实例化,一般用于给子类实例化。
package ClassAbstract;
//抽象类的构造方法
public class Test2_Animal2 {
}
abstract class Animal2{
//抽象类可以有构造方法,但是无法实例化
//用于子类实例化
public Animal2(){
System.out.println("fu..Animal2()");
}
}
class Zi2 extends Animal2{
}
class TestAnimal2{
public static void main(String[] args) {
// Animal2 a2 = new Animal2();//抽象类无法实例化
// Zi2 z=new Zi2();//创建子类实例化对象
Animal2 a2 = new Zi2();//抽象类多用于多态
}
}
1.6接口
java没有多继承,如果想要实现多个类的功能,可以通过实现多个接口来实现。
通过interface关键字创建接口,implements让子类来实现,接口和类之间可以多实现,接口和接口之间可以多继承。
接口里面只有抽象方法,没有构造方法,不可实例化。在创建实现类的对象时默认的super(),是调用的默认Object的无参构造。接口的存在是为了规范和统一标准。
接口支持多继承和多实现。实现的类只有两条路,要么重写实现的所有接口里的所有抽象方法,要么成为抽象类。
接口里面没有成员变量,都是常量,如果在接口里定义一个变量没有写修饰符时,默认会加上public static final。接口里的方法默认就是抽象的,如果不写abstract,会自动补齐。
interface Inte{//定义一个接口
public abstract void show();
}
package Inetface;
public class UseInterface {
public static void main(String[] args) {
}
}
interface Inter3{
abstract void XXX();
}
interface Inter4{
abstract void XXXX();
}
interface Inter0{
abstract void XX();
}
interface Inter00{
abstract void XXx();
}
//关键字implement 可以实现接口。且可以多实现
//实现多接口的类只能全部重写接口里的抽象类
class Inter5 implements Inter3,Inter4 {
public void XXX() {
System.out.println("");
}
public void XXXX() {
}
public void XXXXX() {};
}
//接口可以多继承,继承接口的还是接口,只能在新接口里面添加抽象类
interface Inter6 extends Inter3,Inter4{
//可以继承的时候添加新抽象方法
abstract void XXXXXX();
}
//如果只重写所有接口中的部分抽象方法,这实现的是抽象类
abstract class Inter7 implements Inter3,Inter4{
public void XXX() {
System.out.println("Inter3");
}
}
//Fox实现了Inter5里面的抽象方法,同样继承了Inter0和Inter00里面的抽象方法
abstract class Fox extends Inter5 implements Inter0,Inter00{
}
接口和类的区别
抽象类和接口都不能被实例化,如果要实例化,抽象类变量必须只想实现所有抽象方法的子类对象,接口变量必须只想实现所有接口方法的类对象。
抽象类要被子类继承,接口要被类实现。
接口只能做方法声明,抽象类中可以做方法申明,也可以做方法实现
接口里定义的变量只能是公共的静态常量,抽象类中的变量是普通变量。
抽象类里的方法必须被子类全部实现 ,如果子类不能全部实现父类抽象方法,那么该子类只能是抽象类。同样,一个类实现接口的时候,如不能全部实现接口方法,那么该类也只能是抽象类
抽象方法只能声明,不能实现,接口时设计的结果,抽象类时重构的结果。
抽象类里可以没有抽象方法,如果要扩展抽象类的新方法,子类很容易就能得到这些新方法。
如果一个类里有抽象方法,那么这个类只能是抽象类。
抽象方法要被实现,所以不能是静态类,也不能是私有的。
接口可继承接口,并可多继承接口,但类只能单根继承。
1.7设计模式
Java中有23种设计模式,本质时面向对象设计原则的实际运用,是对类的封装性,继承性和多态性以及类关联关系和组合关系的充分理解。
总体来说设计模式分为三大类:
创建型模式,共五种:工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式。
结构型模式,共七种:适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元模式。
行为型模式,共十一种:策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式。
其实还有两类:并发型模式和线程池模式。
设计模式的六大原则
1、开闭原则(Open Close Principle)
开闭原则就是说对扩展开放,对修改关闭。在程序需要进行拓展的时候,不能去修改原有的代码,实现一个热插拔的效果。所以一句话概括就是:为了使程序的扩展性好,易于维护和升级。想要达到这样的效果,我们需要使用接口和抽象类,后面的具体设计中我们会提到这点。
2、里氏代换原则(Liskov Substitution Principle)
里氏代换原则(Liskov Substitution Principle LSP)面向对象设计的基本原则之一。 里氏代换原则中说,任何基类可以出现的地方,子类一定可以出现。 LSP是继承复用的基石,只有当衍生类可以替换掉基类,软件单位的功能不受到影响时,基类才能真正被复用,而衍生类也能够在基类的基础上增加新的行为。里氏代换原则是对“开-闭”原则的补充。实现“开-闭”原则的关键步骤就是抽象化。而基类与子类的继承关系就是抽象化的具体实现,所以里氏代换原则是对实现抽象化的具体步骤的规范。—— From Baidu 百科
3、依赖倒转原则(Dependence Inversion Principle)
这个是开闭原则的基础,具体内容:真对接口编程,依赖于抽象而不依赖于具体。
4、接口隔离原则(Interface Segregation Principle)
这个原则的意思是:使用多个隔离的接口,比使用单个接口要好。还是一个降低类之间的耦合度的意思,从这儿我们看出,其实设计模式就是一个软件的设计思想,从大型软件架构出发,为了升级和维护方便。所以上文中多次出现:降低依赖,降低耦合。
5、迪米特法则(最少知道原则)(Demeter Principle)
为什么叫最少知道原则,就是说:一个实体应当尽量少的与其他实体之间发生相互作用,使得系统功能模块相对独立。
6、合成复用原则(Composite Reuse Principle)
原则是尽量使用合成/聚合的方式,而不是使用继承。
单例设计模式
单例模式最重要的是确保对象只有一个,控制外界创建对象的个数只能创建1个对象,简单来说,保证一个类在内存中的对象就一个,这样可节约系统内存空间,控制资源的使用。
package cn.tedu.single;
//测试单例设计模式
public class Test8_Single {
public static void main(String[] args) {
Single s = Single.get();
Single s1 = Single.get();
//get()多少次,内存中使用的都是同一个对象
System.out.println(s);//cn.tedu.single.Single@15db9742
System.out.println(s1);//cn.tedu.single.Single@15db9742
}
}
饿汉式
类加载的时候就实例化,并且创建单例对象。
开发步骤:
1、 私有化构造方法
2、 在类的内部创建好对象
3、 对外界提供一个公共的get(),返回一个已经准备好的对象
class Single{
// 1、私有化构造方法,不让外界直接new
private Single() {}
// 2、在类的内部,创建好对象
//static :静态只能调用静态
static private Single s = new Single();
// 3、对外界提供一个公共的get(),返回一个已经准备好的对象
//static是为了外界不通过对象访问而是通过类名直接方法
static public Single get(){
//注意:静态只能调用静态
return s;
}
}
懒汉式
默认不会实例化,什么时候用什么时候new。
class Single{
// 1、私有化构造方法,不让外界直接new
private Single() {}
// 2、在类的内部,创建好对象
//static :静态只能调用静态
static private Single s = null;
// 3、对外界提供一个公共的get(),返回一个已经准备好的对象
//static是为了外界不通过对象访问而是通过类名直接方法
synchronized static public Single get(){
//注意:静态只能调用静态
if(s==null){
s = new Single();//会有安全问题
}
return s;
}
}
2353

被折叠的 条评论
为什么被折叠?



