Java-面向对象(基础篇)-构造方法私有化及对象数组

构造方法私有化及对象数组
一. 构造方法私有化
1. 问题的引出
类的封装性不只体现在对属性的封装上,实际上方法也是可以进行封装的,当然,在方法封装中也包括了对构造方法的封装。
例:

class Singleton{
    private Singleton(){

    }
    public void print(){
        System.out.println("Hello World!");
    }
}

从之前的讲解中可以清楚的知道,一个类想使用,则必须要有实例化的对象,现在要想调用Singleton类中的print()方法则一定要首先产生Singleton的实例化对象,但是由于此时构造方法被私有化了,所以如果按照如下的程序编写,则肯定会出现错误
【错误代码,直接实例化Singleton类对象】

public class SingletonDemo02
{
    public static void main(String[] args){
        Singleton s1=null;
        s1=new Singleton();
        s1.print();
    }
}

程序运行的结果为:

SingletonDemo02.java:13: 错误: Singleton()可以在Singleton中访问private
                s1=new Singleton();
                   ^
1 个错误

从上述错误提示中可以发现,程序是在使用new关键字实例化对象时出现了错误,而对于声明对象则没有任何的错误,那么该如何解释那?
封装是指一切外部不可见性,那么就意味着在外部根本无法调用被封装的构造方法,既然外部不能调用,那么在内部码?
【在内部产生Singleton的对象】

class Singleton{
    static Singleton instance=new Singleton();
    private Singleton(){

    }
    public void print(){
        System.out.println("Hello World!");
    }
}

以上的程序编译后,不会出现任何错误,可以正常的完成instance对象的实例化,即此时的问题在于如何将内部的instance对象传递到类的外部,这样外部就可以通过instance来实例化其他的Singleton的对象。那么对象到底该如何取?
2. 问题的解决
在前面讲解static关键字时曾经讲过,static类型的属性可以由类名称直接调用,所以此时可以将instance属性声明为static类型,这样就可以通过类名称直接调用。
【将instance声明为static类型】

class Singleton{
    static Singleton instance=new Singleton();
    private Singleton(){

    }
    public void print(){
        System.out.println("Hello World!");
    }
}
public class SingletonDemo04
{
    public static void main(String[] args){
        Singleton s1=null;
        s1=Singleton.instance;
        s1.print();
    }
}

运行结果为:

Hello World!

由运行结果可以发现,程序成功地取得了Singleton的实例化对象并调用了print()方法。但是这样做本身也存在着问题,因为类中的属性必须封装,所以此处应该将instance属性进行封装,而封装后必须通过方法取得,但是因为instance属性属于静态属性,所以此处必须声明一个静态方法,这样就可以被类名称直接调用。
【使用静态方法,取得Singleton类的实例】

class Singleton{
    private static Singleton instance=new Singleton();
    private Singleton(){

    }
    public static Singleton getInstance(){
        return instance;
    }
    public void print(){
        System.out.println("Hello World!");
    }
}
public class SingletonDemo05
{
    public static void main(String[] args){
        Singleton s1=Singleton.getInstance();
        Singleton s2=Singleton.getInstance();
        Singleton s3=Singleton.getInstance();
        s1.print();
        s2.print();
        s3.print();
    }
}

运行结果为:

Hello World!
Hello World!
Hello World!
  1. 程序的意义
    在以上的程序中可以发现虽然声明了3个对象,但是实际上所有的对象都只使用一个instance引用,也就是说,此时不管外面如何使用,最终结果程序中也只有一个Singleton类的实例化对象存在,在设计模式中称为单例模式,即无论程序怎么运行,Singleton类永远只有一个实例化对象存在。
    只要将构造方法私有化,就可以控制实例化对象的产生
    二. 对象数组
    对象数组的概念其实并不复杂,所谓的对象数组,就是指包含了一组相关对象的集合,但是在对象数组的使用中读者一定要清楚一点:数组一定要先开辟空间,但是因为其是引用数据类型,所以数组中的每一个对象默认值都是null值,则在使用数组对象中的每一个对象都必须分别进行实例化操作
    【对象数组的声明】
    类 对象数组名称[]=new 类[数组长度];
    【声明一个对象数组】
class Person
{
    private String name;
    public Person(String name ){
        this.name=name;
    }

    public String getName(){
        return this.name;
    }
}
public class ObjectArrayDemo01
{
    public static void main(String args[]){
        Person per[]=new Person[3];
        System.out.println("=======声明数组=======");
        for(int i=0;i<per.length;i++){
            System.out.println(per[i]+"、");
        }       

        per[0]=new Person("张三");
        per[1]=new Person("李四");
        per[2]=new Person("王五");
        System.out.println("\n===========对象实例化==========");
        for(int j=0;j<per.length;j++){
            System.out.println(per[j].getName()+"、"); 
        }
    }
}

运行结果为:

=======声明数组=======
null、
null、
null、

===========对象实例化==========
张三、
李四、
王五、

与数组初始化的方式一样,对象数组也分为静态初始化和动态初始化。以上操作属于数组的动态初始化,静态初始化代码如下,
【对象数组的静态初始化】

class Person{
    private String name ;       // 姓名属性
    public Person(String name){ // 通过构造方法设置内容
        this.name = name ;      // 为姓名赋值
    }
    public String getName(){
        return this.name ;      // 取得姓名
    }
};
public class ObjectArrayDemo02{
    public static void main(String args[]){
        // 声明一个对象数组,里面有三个对象,使用静态初始化方式完成
        Person per[] = {new Person("张三"),new Person("李四"),new Person("王五")} ;
        System.out.println("\n============== 数组输出 =================") ;
        for(int x=0;x<per.length;x++){  // 循环输出
            System.out.print(per[x].getName() + "、") ;  // 此时,已经实例化完成了,所以会直接打印出姓名
        }
    }
};

运行结果为:

============== 数组输出 =================
张三、李四、王五、

程序中在声明对象数组是采用了静态初始化的方式,然后采用循环的方式依次输出对象数组中的每一个元素。
注:主方法中String agrs[]就是对象数组。在主方法中,可以使用String args[]接收初始化参数,实际上这里的String本身就是一个类,所以在主方法中的参数本身就是以对象数组的形式出现的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

aotulive

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值