返回列表 发新帖

【Android入坑系列教程】40.static关键字---面向对象

[复制链接]

62

主题

722

回帖

2756

积分

大学生

Rank: 5Rank: 5

金币
2029
好评
12
信誉
100

考神

发表于 2019-3-29 12:43:32 | 显示全部楼层 | 阅读模式  来自 四川
本帖最后由 pansong291 于 2019-3-30 11:46 编辑

上篇:39.函数的参数传递---面向对象
下篇:41.内部类---面向对象

注意:如果你的回复只是“感谢分享”、“辛苦了”之类的与教程内容无关的字眼,还请不要回复本帖,谢谢合作!!!
注意:如果你的回复只是“感谢分享”、“辛苦了”之类的与教程内容无关的字眼,还请不要回复本帖,谢谢合作!!!
注意:如果你的回复只是“感谢分享”、“辛苦了”之类的与教程内容无关的字眼,还请不要回复本帖,谢谢合作!!!


静态变量
当我们编写一个类时,其实就是在描述其对象的属性和行为,而并没有产生实质上的对
象,只有通过 new 关键字才会产生出对象,这时系统才会分配内存空间给对象,其方法才可
以供外部调用。
我们有时候希望无论是否产生了对象或无论产生了多少对象的情况下,某些特定的数据
在内存空间里只有一份,例如所有的中国人都有个国家名称,每一个中国人都共享这个国家
名称,不必在每一个中国人的实例对象中都单独分配一个用于代表国家名称的变量。如图
3.19 所示:

虽然,在各实例对象中没有分配 country 这个变量,但我们可以在程序中通过中国人的
实例对象来访问这个变量,要实现这个效果,我们只需要在类中定义的 coutry 变量前面加
static 关键字即可,我们称这种变量为静态成员变量。我们也可以直接使用类名来访问
这个 country 这个变量,还可以在类的非静态的成员方法中象访问其他非静态成员变量一样
去访问这个静态成员变量。静态变量在某种程度上与其它语言的全局变量相类似,如果不是
私有的就可以在类的外部进行访问,此时不需要产生类的实例对象,只需要类名就可以引用。
class Chinese
{
    static String country="中国";
    String name;
    int age;
    void singOurCountry()
    {
        System.out.println("啊!亲爱的" + country);
        //类中的成员方法也可以直接访问静态成员变量
    }
}
class TestChinese
{
    public static void main(String [] args)
    {
        System.out.println("Chinese country is " + Chinese.country);
        //上面的程序代码直接使用了“类名.成员”的格式
        Chinese ch1 = new Chinese();
        System.out.println("Chines country is " + ch1.country);
        //上面的程序代码直接使用了“对象名.成员”的格式
        ch1.singOurCountry();
    }
}
注意:我们不能把任何方法体内的变量声明为静态,如下面这样是不行的:
fun()
{
    static int i = 0;
}
static 标识符修饰的变量,它们在类被载入时创建,只要类存在,static 变量就存
在。由于静态成员变量能被各实例对象所共享,所以我们可以用它来实现一些特殊效果,如
我们想统计在程序中一共产生了多少某个类的实例对象,可以用下面的方法统计:
class A
{
    private static int count = 0;
    public A()
    {
        count = count + 1;
    }
}
在上面的程序中,每产生一个类 A 的实例对象,都会调用类 A 的构造方法,我们在构造
方法中将 count 加 1,就可以统计出总共产生了多少个类 A 的实例对象,为了防止外面的程
序直接修改 count 变量,我们用 private 关键字限定了 count 变量的访问权限。

静态方法
我们有时也希望不必创建对象就可以调用某个方法,换句话说也就是使该方法不必和对
象绑在一起。要实现这样的效果,我们只需要在类中定义的方法前加上 static 关键字即可,
我们称这种方法为静态成员方法。同静态成员变量一样,我们可以用类名直接访问静态成员
方法,也可以用类的实例对象来访问静态成员方法,还可以在类的非静态的成员方法中象访
问其他非静态方法一样去访问这个静态方法,如下面的程序代码:
class Chinese
{
    static void sing()
    {
        System.out.println("啊!");
    }
    void singOurCountry()
    {
        sing();
        //类中的成员方法也可以直接访问静态成员方法
    }
}
class TestChinese
{
    public static void main(String [] args)
    {
        Chinese.sing();
        //上面的程序代码直接使用了“类名.成员”的格式
        Chinese ch1 = new Chinese();
        ch1.sing();
        //上面的程序代码直接使用了“对象名.成员”的格式
        ch1.singOurCountry();
    }
}
类的静态成员经常被称作“类成员”(class members),对于静态成员变量,我们叫类属
性(class attributes),对于静态成员方法,我们叫类方法(class methods)。采用 static
关键字说明类的属性和方法不属于类的某个实例对象,我们在前面的多个例子程序中反复用
到的 System.out.println()语句,其中,System 是一个类名,out 是 System 类的一个静态
成员变量,println()方法则是 out 所引用的对象的方法。
在使用类的静态方法时,我们要注意以下几点:
1).在静态方法里只能直接调用同类中其它的静态成员(包括变量和方法),而不能直接
访问类中的非静态成员。这是因为,对于非静态的方法和变量,需要先创建类的实例对象后
才可使用,而静态方法在使用前不用创建任何对象。
2).静态方法不能以任何方式引用 thissuper 关键字(super 关键字在下一章讲解)。
与上面的道理一样,因为静态方法在使用前不用创建任何实例对象,当静态方法被调用时,
this 所引用的对象根本就没有产生。
3).main()方法是静态的,因此 JVM 在执行 main 方法时不创建 main 方法所在的类的实
例对象,因而在 main()方法中,我们不能直接访问该类中的非静态成员,必须创建该类的
一个实例对象后,才能通过这个对象去访问类中的非静态成员,这种情况,我们在以后的例
子中会多次碰到。
对于上面的几个注意点,不必要死记硬背,只要从原理上去想为什么,反而很容易记住。

静态代码块
一个类中可以使用不包含在任何方法体中的静态代码块(static block ),当类被载入
时,静态代码块被执行,且只被执行一次,静态块经常用来进行类属性的初始化。如下面的
程序代码:
class StaticCode
{
    static String country;
    static
    {
        country = "china";
        System.out.println("StaticCode is loading");
    }
}
class TestStaticCode
{
    static
    {
        System.out.println("TestStaticCode is loading");
    }
    public static void main(String [] args)
    {
        System.out.println("begin executing main method");
        new StaticCode();
        new StaticCode();
    }
}
编译运行上面的程序,结果如下:
TestStaticCode is loading
begin executing main method
StaticCode is loading

StaticCode 中的静态代码块被自动执行,尽管我们产生了类 StaticCode 的两个实例
对象,但其中的静态代码块只被执行了一次。上面的例子也反过来说明,当一个程序中用到
了其他的类,才会去装载那个类。因此,我们得出这个结论:类是在第一次被使用的时候才
被装载,而不是在程序启动时就装载程序中所有可能要用到的类。

单态设计模式
设计模式是在大量的实践中总结和理论化之后优选的代码结构、编程风格、以及解决问
题的思考方式。设计模式就像是经典的棋谱,不同的棋局,我们用不同的棋谱,免得我们自
己再去思考和摸索。失败为成功之母,但是要以大量的时间和精力为代价,如果有成功经验
可借鉴,没有人再愿意去甘冒失败的风险,我们没有理由不去了解和掌握设计模式,这也是
Java 开发者提高自身素质的一个很好选择。使用设计模式也许会制约你去创新,不过真正
有意义的创新只能出自少数天才,即使你就是那个天才,虽不必因循守旧,但也不可能完全
不去了解和借鉴前人的成功经验。
所谓类的单态设计模式,就是采取一定的方法保证在整个的软件系统中,对某个类只能
存在一个对象实例,并且该类只提供一个取得其对象实例的方法。
如果我们要让类在一个虚拟机中只能产生一个对象,我们首先必须将类的构造方法的访
问权限设置为 private,这样,就不能用 new 操作符在类的外部产生类的对象了,但在类内
部仍可以产生该类的对象。因为在类的外部开始还无法得到类的对象,只能调用该类的某个
静态方法以返回类内部创建的对象,静态方法只能访问类中的静态成员变量,所以,指向类
内部产生的该类对象的变量也必须定义成静态的。下面是一个单态类的程序例子:
public class TestSingle
{
    private static final TestSingle onlyOne=new TestSingle();
    public static TestSingle getTestSingle()
    {
        return onlyOne;
    }
    private TestSingle(){}
}
对于上面的程序,我们在外面只能调用 TestSingle.getTestSingle() 方法获得 TestSingle
的对象。我的一些学员告诉我,有些用人单位对于考察应聘者这样的知识点乐此不疲,
希望刚才这句话,能对那些想通过学习 Java 编程去找工作的读者有所帮助。

理解 main 方法的语法
在前面的章节中,我们已经多次看到,如果一个类要被 Java 解释器直接装载运行,这
个类中必须有 main()方法,有了前面所有的知识,读者现在可以理解 main 方法的定义了。
由于 Java 虚拟机需要调用类的 main()方法,所以该方法的访问权限必须是 public,又因为
Java 虚拟机在执行 main()方法时不必创建对象,所以该方法必须是 static 的,该方法接收
一个 String 类型的数组参数,该数组中保存执行 Java 命令时传递给所运行的类的参数。

上篇:39.函数的参数传递---面向对象
下篇:41.内部类---面向对象

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

6

主题

51

回帖

218

积分

初中生

Rank: 3Rank: 3

金币
15
好评
0
信誉
100
发表于 2019-3-29 12:47:29 来自手机  | 显示全部楼层  来自 新疆
楼主66666666
回复

使用道具 举报

6

主题

51

回帖

218

积分

初中生

Rank: 3Rank: 3

金币
15
好评
0
信誉
100
发表于 2019-3-29 12:48:58 来自手机  | 显示全部楼层  来自 新疆
提示: 该帖被管理员或版主屏蔽
回复

使用道具 举报

9

主题

715

回帖

1617

积分

高中生

Rank: 4

金币
196
好评
1
信誉
100
QQ
发表于 2019-3-29 12:55:40 来自手机  | 显示全部楼层  来自 广东
感谢分享
回复

使用道具 举报

0

主题

380

回帖

822

积分

高中生

Rank: 4

金币
195
好评
1
信誉
100
发表于 2019-4-27 10:43:25 | 显示全部楼层  来自 河南
提示: 作者被禁止或删除 内容自动屏蔽
回复

使用道具 举报

7

主题

2323

回帖

4081

积分

大学生

Rank: 5Rank: 5

金币
635
好评
2
信誉
100
发表于 2020-6-16 11:05:01 | 显示全部楼层  来自 广东
帮顶一下
回复

使用道具 举报

发表回复

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

快速回复 返回顶部 返回列表