派生类将其本身与基类区别开来的方法是添加数据成员和成员函数。因此,继续的机制将使得在创建新类时,只需说明新类与已有类的区别,从而大量原有的程序代码都可以复用,所以有人称类是“可复用的软件构件”
二、各个变量在类加载的时候的初始化顺序
public class StaticTest{ public static void main(String args[]){ staticFunction(); } static StaticTest st = new StaticTest(); static{ System.out.println("1"); } StaticTest(){ System.out.println("3"); System.out.println("a="+a+" b="+b); } public static void staticFunction(){ System.out.println("4"); } { System.out.println("2"); } int a=100; static int b=112;}
我们先来看一下各个变量在类加载的时候的初始化顺序:
1、初始化父类的静态变量,静态代码块,初始化的顺序按照出现顺序。 2、初始化子类的静态变量,静态代码块。 3、初始化父类的成员变量。 4、执行父类的构造函数。 5、初始化子类的成员变量。 6、构造代码块创建对象时执行。 7、执行子类的构造函数。 执行的结果为: 2 3 a=100,b=0 1 4 产生这个结果的原因的关键在这一句话: static StaticTest st = new StaticTest();st变量的引用是本类的实例,因此在实例化st变量时,将实例初始化嵌入到静态初始化中。因为这一句放在静态初始化的开头,所以static int b=112没有被调用,输出的b=0,同时,输出1也在2和3后面。在对象的初始化时,也是先初始化环境变量,再执行构造函数,a的值为100。
静态数据成员
假如我们要设计一个战争游戏,游戏中有许多的兵种。游戏的过程中,每隔一段时间每个兵种都会产生,同时由于战争的消耗,每个兵种士兵的数量又会减少。为了情节更逼真呐,我们引入了一个士气的概念,当士气比较高的时候,这个兵种的士气战斗力就会很强,士气较低的时候,兵种的战斗力就会比较弱。兵种的士气受很多因素影响,其中一个最直接的因素就是士兵的数量相关,它与数量成正比。我们就需要一组全局变量,每个变量都会记录当前兵种的数量,但是使用全局变量会引入很多的问题,使用全局变量的安全得不到保障,我们可以在程序的任何地方修改它的值。全局变量还可能导致命名空间的污染,当程序比较大的时候,各个模块之间有可能冲突。那如果不使用全局变量,我们就可以使用静态的数据成员。
静态数据成员:以static开头。静态数据成员为各个对象共有,不属于某个具体的对象,所有对象都可以对它进行引用,都可以读取和修改。若一个对象修改了该静态成员的值,则在其他各个对象中该数据成员的值都会同时改变。
定义类时就为静态数据成员分配空间,不随对象的建立而分配空间。可以说它是属于这个类的,定义完类之后就可以引用。
1.定义方法
static int count;//定义了一个int类型的静态数据成员,它的定义是在类里面,但是初始化不可以在类的里面类外面初始化 (你可以在类的实现文件里面初始化):int CTime::count=0;//初始化不要再加static
2.调用方法
1)类名::静态成员
2)对象名.静态成员
在类内的静态数据成员仅仅是对该成员的声明,同时还需要在类外部进行定义。
当我们在构造函数里面对它++然后输出,在析构函数里面—输出就得到这样的结果:构造函数调用的次数就是创建对象的个数,析构函数调用的次数就是销毁对象的次数。
静态成员函数
在声明成员函数时在函数前添加static关键字就定义了静态成员函数。
与静态数据成员一样,静态成员函数也是类的一部分。
1.声明静态成员函数
static int func(); //定义的时候不需要static关键字
2.调用静态成员函数
1)类名::静态成员函数
2)对象名.静态成员函数
静态成员函数一般是为了处理静态的数据成员。
与一般成员函数的区别:
1)非静态成员函数有this指针,静态成员函数没有this指针。
2)因为它可以在未定义类对象时就可以引用。因此静态成员函数不能访问本类中的非静态成员(没有this指针,就不能通过引用调用成员函数和数据成员)