猜单词小程序中的OOP设计原则---征服OOP的思维方式05

因为上上次举了个例子,昨天和女朋友道了一天的歉,所以昨天没有更博,哎,女朋友就是麻烦!不过我也很无奈啊,毕竟我还不想恢复我单身狗的身份!好了,接着上次的话题,这次给大家介绍内存优化。
上次给大家介绍了OOP的三大特点之一的封装,将数据和对数据的操作放在一起,从而保证了数据的安全。那么问题来了!!!!
如果当我们需要很多功能类的时候,如果对每个类都去创建该类的对象的话是非常消耗内存的,要知道在Java中,每使用一次new关键字就会在堆内存中开辟空间。(关于内存结构后续的文章中会为大家提到)
回顾一下我们猜单词小程序中的Start这个类

public class Start {
    public void init() {
        //创建sq对象
        SqlDemo sq = new SqlDemo();
        //调用该对象的getArr1()方法获取正确的中文意思
        String str1 = sq.getArr1();
        //创建in对象
        Input in = new Input();
        //调用该对象的getAns()方法获取用户输入的值
        String str2=in.getAns();
        //创建ju对象
        Judge ju = new Judge();
        //调用该对象的contrast方法来判断用户的答案是否正确
        boolean flag = ju.contrast(str1, str2);
        //创建show对象
        Show show = new Show();
        //调用该对象的showMessage方法来显示用户的反馈信息
        show.showMessage(flag);
    }
}

这个类中创建了好几个对象,这还是在一个小程序中,咱们想想,如果是在大型的项目中,难道就这么不停的创建对象吗?(当然OOP的思想就是创建对象,再去通过对象调用方法)但是如果有100个类难道就去创建100个对象吗?如果是1000个呢??毫无疑问,这样是不明智的。对于这种情况就需要对内存进行优化了。
在Java中提供了一个关键字static,表示静态的意思。
看一下官方的解释:
static:静态成员修饰符,被static修饰后的成员,在编译时由内存分配一块内存空间,直到程序停止运行才会释放!
肯定不好理解对吧,没关系,我们只需要从上面的官方解释里知道:当一个类在编译时期,系统就会给static分配一块内存空间,而这个时候内存里还没有任何对象!(关于这个很好理解,大家只需要记住,只有new出现的时候才会有对象的存在)。也就是说static成员对该类的所有对象都是可见的!!!对不对!
因为static成员早先一步进入内存嘛!这一点大家一定要明白!
所以,在一个类中,被static修饰的成员对于该类所有的对象都是可见的,也就是说该成员可以被该类的所有对象访问,对不对!!!
好了,关于概念就给大家介绍到这里了!下面来说说static成员怎么访问呢?
首先,毫无疑问肯定是能够通过对象去访问的,但是上面就说了,static成员在对象还不存在的时候就已经在内存中分配空间了,那么在对象还没有被创建的时候怎么去访问呢??
在Java中,提供了一种专门的方式去访问static成员,就是通过类名直接去访问!!!
那么问题来了,这样做的好处是什么呢?
好处肯定就是你不用创建对象了嘛,直接用类名去调用。所以static成员也被叫做类成员。来体会一下下面的这段代码:

public class SqlDemo {
    //私有化构造方法,防止外部创建本类对象
    private SqlDemo() {
    }
    //私有化共享数据,防止外界对数据的篡改,保证数据的安全性
    private static String[] arr1= {"deprecated","category","figure","confirm","profile","argument"};
    private static String[] arr2= {"不赞成","类型","数字","确认","侧面","争论"};

    //对外提供公有的访问方法
    public static String getArr1() {
        int i= (int)(Math.random()*arr1.length);
        System.out.println(arr1[i]);
        return arr2[i];
    }
}

这是把前面的猜单词小程序中的SqlDemo类进行了改进,
大家以看到,两个字符串数组都被static修饰了。同样的geArr1方法也被静态修饰了。(构造方法下文中会解释!)
这样做的好处就是可以通过类名去调用getArr1方法获取数组中的元素,而不用去创建SqlDemo类的对象。
同样的,来看下面的这一段代码:

public class Input {

    //私有化构造方法,防止外部创建本来对象
    private Input(){

    }
    // 创建键盘录入对象
    Scanner in = new Scanner(System.in);

    public String getAns() {
        // 接受用户的输入值
        String sum = in.nextLine();
        // 返回用户输入的值
        return sum;
    }
    //对外提供共有方法,返回一个本类对象
    public static Input getInput() {
        return new Input();
    }
}

同样的,该类中提供了一个static方法getInput,(其实可以直接将getAns方法用static修饰即可,不过这里小风主要是想给大家介绍一种设计模式–单例模式,所以才多定义了一个方法)
好了,来解释一下这段代码。emmmm 想了想,要解释这段代码的话还要给大家提一个概念,就是new关键字,现在就来解释一下new关键字把,
来看看官方的解释:new关键字的作用就是在你声明了一个对象后,给对象分配相应内存
当然大家肯定理解不了,没关系。来回顾一下之前的代码。

SqlDemo sq = new SqlDemo();
Input in = new Input();

看这两行代码,new关键字后的内容都是一个和类名相同的一个方法,对不对!好了,先给大家说,这个方法叫做构造方法,大家先不要慌,对于构造方法官方的解释是用于初始化对象,没错!
你想想,当new关键字执行之后,系统就会在内存中分配一块内存空间来存放该对象,这个时候就需要这个方法来对该对象进行初始化。
好了,关于构造方法会在下一回给大家详细的介绍。
回到这次的话题中,上述的两段代码中不难发现,开头都有一段代码,相信大家都已经能够知道是什么吧,
没错,就是构造方法!但是再仔细一看,构造方法被private修饰了!!这是为什么呢???
相信大家从注释中已经看到了这样的目的吧,没错,就是构造方法私有化,返防止外界创建本类的对象!
那么问题来了!为什么要防止外部创建本类的对象呢??
好了,第一点肯定是安全嘛,也就是保证了对象的唯一性。另外一点就是优化内存!
你想想:当系统中只存在一个对象的时候,对于一些需要频繁创建和销毁的对象来说,采用单例模式无疑可以提高系统的性能。因此这种方式可以节约系统资源,
好了,在Java开发中经常会遇到共享数据的问题,对于这种问题,一般多采用单例来解决。额 ,说的有点操之过急哈!
单例模式就是将一个类中的构造方法私有化,通过本类中的公有方法对外部返回一个本类的对象。Input类就是一个典型的单例模式。
好了,关于单例模式就先给大家介绍到这里,大家只需要知道,单例模式的核心思想就是将构造方法私有化,防止外部创建本类对象。
好了,回到我们的猜单词的小程序中,既然改变了SqlDemo和Input类,那么我们对其他类也做一下优化,先来看看Show类

public class Show {
    public static void showMessage(boolean flag) {
        if (flag) {
            System.out.println("恭喜你答对了!");
        }
        else {
            System.out.println("不好意思,你答错了");
        }
        return;
    }
}

看,showMessage方法被修饰成了静态成员,于是在Start类中就不用去创建该类的对象了,因此,直接同通过类名去调用就可以了。
再看Start类:

public class Start {
    //不需要每次显示结果是否正确
    public static boolean init() {
        String str1 = SqlDemo.getArr1();
        String str2=Input.getInput().getAns();
        boolean flag = Judge.contrast(str1, str2);
        return flag;
    }
    //需要每次显示结果是否正确
    public void show() {
        String str1 = SqlDemo.getArr1();
        String str2=Input.getInput().getAns();
        Judge ju = new Judge();
        boolean flag = ju.contrast(str1, str2);
        Show.showMessage(flag);
    }

}

看第一个init()方法中,不用创建他们的对象就能够获取到他们的方法,
同时,静态依然保留了通过对象去访问的访问规则,比如show()方法里还是可以去创建Judge的对象ju,然后通过ju去访问方法。
好了,到这里就已经差不多结束了。
来看一下咱们的程序的入口:

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

简单吗?大家可能有点好奇,new Start().show();
是啥意思。不要慌,下一篇文章中将会给大家介绍!
额 ,对了,别忘了把Judge类中的方法也用static修饰哈!
哎,算了,还是给出程序的完整到代码把:

package oopDemo3;
/**
 * 
 * */
public class SqlDemo {
    //私有化构造方法,防止外部创建本类对象
    private SqlDemo() {

    }
    //私有化共享数据,防止外界对数据的篡改,保证数据的安全性
    private static String[] arr1= {"deprecated","category","figure","confirm","profile","argument"};
    private static String[] arr2= {"不赞成","类型","数字","确认","侧面","争论"};

    //对外提供公有的访问方法
    public static String getArr1() {
        int i= (int)(Math.random()*arr1.length);
        System.out.println(arr1[i]);
        return arr2[i];
    }
}
package oopDemo3;

import java.util.Scanner;

/**
 * 用来实现用户从键盘输入一个字符串的功能
 * 
 */
public class Input {

    //私有化构造方法,防止外部创建本来对象
    private Input(){

    }
    // 创建键盘录入对象
    Scanner in = new Scanner(System.in);

    public String getAns() {
        // 接受用户的输入值
        String sum = in.nextLine();
        // 返回用户输入的值
        return sum;
    }
    //对外提供共有方法,返回一个本类对象
    public static Input getInput() {
        return new Input();
    }
}
package oopDemo3;

/**
 * 判断用户的输入是否正确
 * 
 * */
public class Judge {
        public static boolean contrast(String arr1,String arr2) {
        return arr1.equals(arr2);   
    }

}
package oopDemo3;
/**
 * 给用户反馈信息
 * 
 * */
public class Show {
    public static void showMessage(boolean flag) {
        if (flag) {
            System.out.println("恭喜你答对了!");
        }
        else {
            System.out.println("不好意思,你答错了");
        }
        return;
    }
}
package oopDemo3;
/**
 * 实现代码的逻辑功能
 * 
 * */
public class Start {
    //不需要每次显示结果是否正确
    public static boolean init() {
        String str1 = SqlDemo.getArr1();
        String str2=Input.getInput().getAns();
        boolean flag = Judge.contrast(str1, str2);
        return flag;
    }
    //需要每次显示结果是否正确
    public void show() {
        String str1 = SqlDemo.getArr1();
        String str2=Input.getInput().getAns();
        Judge ju = new Judge();
        boolean flag = ju.contrast(str1, str2);
        Show.showMessage(flag);
    }

}
package oopDemo3;

public class Test {

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

好了,这才是一个完整的Java小程序。
大家快去试试吧!
下一篇我们就进入到了Java中的OOP思想的核心部分了!期待不

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值