Day5:面向对象的定义(下)

1、单例模式

/*

设计模式:对普遍常见问题,通用的解决办法。
          23种。其实就是解决问题的思想。

单例设计模式:
    解决的问题:保证一个类在内存中的对象唯一性。


如何保证一个类的对象唯一性呢?

思路:
1,不让其他程序创建该类对象。
2,其他程序不能创建,只有在本程序中创建一个对象。
3,将自定义的对象提供给其他程序访问。


步骤:
1,私有化构造函数。
2,自己new一个本类对象。
3,对外提供一个方法可以获取到这个对象。

*/
//饿汉式
class Single
{
    //创建一个本类对象。
    private static Single s = new Single();

    //私有化构造函数。
    private Single(){}

    //对外提供方法,让其他程序获取该对象。
    //结果?Single
    //参数/ 无。
    public static Single getInstance()
    {
        return s;
    }
}

class SingleDemo 
{
    public static void main(String[] args) 
    {
        Single s1 = Single.getInstance();
        Single s2 = Single.getInstance();
        System.out.println(s1==s2);
    }
}
//懒汉式,延迟加载方式。
//存在一些小问题,这是涉及到多线程技术的。
class Single
{
    private static Single s = null;
    private Single(){}

    public static Single getInstance()
    {
        if(s==null)
            s = new Single();
        return s;
    }
}




class Single2
{
    private static final Single2 s =  new Single2();
    private Single2(){}
    
    public static Single2 getInstance()
    {
        return s;
    }
    /**/
}
class SingleDemo2 
{
    public static void main(String[] args) 
    {
        
//        Single2 s1 = Single2.s;
//        Single2 s2 = Single2.s;

//        System.out.println(s1==s2);
    }
}

单例图解

2、对象的特点------继承

/*
继承:提高了代码的复用性。
      让类与类之间产生了关系,给多态这个特征提供了前提。


特点:
1,java中不直接在类上体现多继承。只支持单继承。
多继承:一个子类可以继承多个父类。
class Fu1
{
    void show(){}
}
class Fu2
{
    void show(){}
}

class Zi extends Fu1,Fu2
{
}
new Zi().show();//出现了调用的不确定性。在方法体上不确定。

单继承:一个子类只能继承一个父类。


多层继承:就会出现继承体系,学习一个体系的时候,先看最顶层的类。使用最底层的类创建对象调用方法。



什么时候写继承?
事物之间存在着所属(is a)关系时,才继承。xxx是yyy中的一种。
xxx继承yyy。
比如:狗继承犬科,狼继承犬科。



*/

class Person
{
    private String name;
    int age;
    public String getName()
    {
        return this.name;
    }
}


class Student extends/*继承*/Person
{
    void study()
    {
        System.out.println(getName()+":"+age+" good good study...");
    }
}


class Worker extends Person
{
    
    void work()
    {
        System.out.println(name+":"+age+"....work");
    }
}


class ExtendsDemo 
{
    public static void main(String[] args) 
    {
        Student s = new Student();
//        s.name="李四";
        s.age=12;
        s.study();
    }
}

/*
class A
{
    void show(){}
}


class B
{
    A a;

    B(A a)
    {
        this.a = a;
    }
    public void method()
    {
        a.show();
    }
}
*/
/*
继承中,子类里,成员的特点。
成员变量。

成员函数。

构造函数。

*/

//成员变量。
/*
super关键字:
super关键字的用法和this相似。

this代表的是当前对象。
super代表的是父类中内存空间。

子父类中不会出现同名属性的情况。

*/

class Fu
{
    int num = 4;

}
class Zi extends Fu
{
    int num = 5;
    void show()
    {
        int num = 6;
        System.out.println("num="+super.num);
        System.out.println(this);
//        System.out.println(super);//不可以。
    }
}
class ExtendsDemo2 
{
    public static void main(String[] args) 
    {
        new Zi().show();
    }
}
/*
继承中,成员函数的特点。

特殊情况:
子父类中出现了一模一样的方法,创建子类对象调用该方法时,运行的是子类中的方法。
这种情况称之为函数的另一个特性----覆盖(override)重写 复写。


继承的覆盖使用注意事项:

1,子类覆盖父类权限必须大于等于父类的权限。
2,覆盖中,静态只能覆盖静态,或者被静态覆盖。




*/

class Fu
{
    public void show()
    {
        System.out.println("fu show");
    }
}

class Zi extends Fu
{
    public void show()
    {
        System.out.println("zi show");
    }
}

class ExtendsDemo3 
{
    public static void main(String[] args) 
    {
        Zi z = new Zi();
        z.show();
//        Phone p = new Phone();
//        NewPhone p = new NewPhone();
//        p.show();
    }
}


/*

覆盖的应用。

新电话的功能
来电显示 除了号码,还显示姓名,大头贴。

*/
class Phone
{
    public void call(){}
    //来电显示。
    public void show()
    {
        System.out.println("number");
    }

}
//新电话描述。
/*
覆盖的应用:沿袭父类的功能声明,定义子类该功能的特有内容。

*/
class NewPhone extends Phone
{
    public void show()
    {
//        System.out.println("number");
        super.show();
        System.out.println("name");
        System.out.println("pic");
    }
}
/*
子父类中的构造函数的特点。

创建子类对象,父类中的构造函数也运行了。
为什么呢?
其实在子类的所有构造函数中的第一行,都有一句默认的super();在调用父类中的空参数构造函数。
为什么子类实例化都必须去父类中的初始化呢?
因为子类继承了父类,只有了父类中的内容,所以子类在实例化使用父类中的内容之前,
必须要先明确父类是如何对自己的内容进行初始化的,
所以子类的构造函数都会默认访问父类中空参数的构造函数。通过super();

如果父类中没有空参数的构造函数时,子类的构造函数必须通过super执行要访问的父类中的构造函数。


this()和super();都必须出现在构造函数的第一行。
为什么都必须出现的第一行呢?因为初始化的动作要先执行。



*/
class Fu extends Object
{
    Fu()
    {
        //super();
        //显示初始化。
        //构造代码块初始化。
        System.out.println("fu run...");
    }
    /**/
    Fu(int x)
    {
        System.out.println("fu ..."+x);
    }
}
class Zi extends Fu
{
    Zi()
    {
//        super();
        
        System.out.println("Zi run...");
    }
    Zi(int x)
    {
        this();
        System.out.println("Zi ..."+x);
    }
}

class ExtendsDemo4 
{
    public static void main(String[] args) 
    {
        new Zi(4);
    }
}

class Fu
{
    {
        System.out.println("fu's constructor code.... num="+x);
    }
    Fu()
    {

        x = 8;
        System.out.println("fu's constructor..... "+getNum());
    }
    int getNum()
    {
        return x;
    }
    void show()
    {
        System.out.println("show ...."+getNum());//9
    }
}
class Zi extends Fu
{
    int y = 4;
    {
        System.out.println("zi's constructor code....num="+y);
    }
    Zi()
    {
        y = 9;
    }
    int getNum()
    {
        return y;
    }
}

//画图求解。

class ExtendsTest
{
    public static void main(String[] args) 
    {
        new Zi().show();
    }
}

3、Final关键字

/*
final关键字。最终。

1,final修饰类,函数,变量。
2,final修饰的类不可以被继承。
3,final修饰的方法不可以被覆盖。
4,final修饰的变量是一个常量,只能被赋值一次。



程序中不变的数据都用final修饰,提供程序的阅读性。
*/

class Fu
{
    /*final*/ void show()
    {
        //访问了系统中的内容。
    }
}
class Zi extends Fu
{
    final double PI = 3.14;
    public static final int NUM = 8;
    void show()
    {
        final int MY_COUNT = 4;
    
        System.out.println(MY_COUNT);
    }
}



class FinalDemo
{
    public static void main(String[] args) 
    {
        System.out.println("Hello World!");
    }
}

//饿汉式 需要加final。
class Single
{
    private static final Single INSTANCE = new Single();
}
//懒汉式 别加final修饰。
class Single
{
    private static  Single s = null;
    private Single(){}
    public static Single getInstance()
    {
        if(s==null)
            s = new Single();
        return s;
    }
}
原文地址:https://www.cnblogs.com/vijay/p/3502931.html