一、静态变量和静态函数
1、Java 中被 static 修饰的成员称为静态成员或类成员。它属于整个类所有,而不是某个对象所有,即被类的所有对象所共享。静态成员可以使用类名直接访问,也可以使用对象名进行访问。
我们首先需要了解什么是静态变量,以及其与非静态变量有何种区别。
静态变量
静态变量也称为类变量,在类的对象之间通用,并且也可以使用类名来访问此变量。
非静态变量
非静态类的任何变量称为非静态变量或实例变量。
静态与非静态变量的示例
JavaTester.javapublic class JavaTester {undefined
public int counter = 0;
public static int staticCounter = 0;
public JavaTester(){undefined
counter++;
staticCounter++;
}
public static void main(String args[]) {undefined
JavaTester tester = new JavaTester();
JavaTester tester1 = new JavaTester();
JavaTester tester2 = new JavaTester();
System.out.println("Counter: " + tester2.counter);
System.out.println("Static Counter: " + tester2.staticCounter);
}
}
输出结果Counter: 1
Static Counter: 3
2、静态变量的应用
1)、保存跨对象信息
Class Kongfu{
Static String loginAccount;
}
2)、存储对象个数
3、静态变量的优势
可以节省内存,因为它是所有对象所公有的,因此,对多个对象来说,静态
数据成员只存储一处,供所有对象共用。静态数据成员的值对每个对象都是一样,
但它的 值是可以更新的。只要对静态数据成员的值更新一次,保证所有对象存
取更新后的相同的值,这样可以提高时间效率。
注意:
(1)类的静态成员函数是属于整个类而非类的对象,所以它没有this指针,
这就导致了它仅能访问类的静态数据和静态成员函数。
(2)不能将静态成员函数定义为虚函数。
(3)由于静态成员声明于类中,操作于其外,所以对其取地址操作,就多少
有些特殊,变量地址是指向其数据类型的指针 ,函数地址类型是一个
“nonmember函数指针”。
(4)由于静态成员函数没有this指针,所以就差不多等同于nonmember函数
结果就产生了一个意想不到的好处:成为一个callback函数,使得我们得以将
c++和c-based x window系统结合,同时也成功的应用于线程函数身上。
(5)static并没有增加程序的时空开销,相反她还缩短了子类对父类静态成
员的访问时间,节省了子类的内存空间。
(6)静态数据成员在<定义或说明>时前面加关键字static。
(7)静态数据成员是静态存储的,所以必须对它进行初始化。
(8)静态成员初始化与一般数据成员初始化不同;
二、封装
设计一个类时,应该对成员变量的访问做出一些限定,不允许外界随意访问,这就需要实现封装。将类中的属性私有化,即用private关键字来修饰。私有属性只能在它所在的类中被访问。如果外界想要访问私有属性,需要提供一些使用public修饰的公有方法。(这一部分我在浅谈一中已谈及,详情请见上一篇博客)
1)、实现封装
实现封装有以下两个步骤:
(1)将不能暴露的成员隐藏起来,例如Customer类中的age,不能让其在类的外部被直接赋值。实现方法是将该成员定义为私有的,在成员定义前加上修饰符private。
(2)用公共方法来暴露对该隐藏成员的访问,可以给函数加上修饰符public,将该方法定义为公共的。
class Student{
private int a;
public int getA() {
return a;
}
public void setA(int a) {
if (a<0){
System.out.println("成绩无效");
}
else{
this.a = a;
}
}
}
public class test {
public static void main(String[] args) {
Student b=new Student();
Student c=new Student();
b.setA(-12);
c.setA(75);
System.out.println(b.getA());
System.out.println(c.getA());
}
}
输出结果:
成绩无效
0
75
这里为什么会输出0,是因为实例变量永远会有默认值,如果你没有明确的赋值给实例变量,或者没有调用setter,实例变量还是会有值。int类型值为0,float类型值为0.0,Boolean类型为false。注意局部变量没有默认值。
注意:
- 私有成员只能在定义它的内部被访问,在类的外部不能被访问。
- 一般情况下,可以将成员变量定义为private的,通过pubilc函数(方法)对其进行访问。
- Private和public都是访问区分符。
三、包
在开发过程中,会定义很多类,随着类越写越多,难免会出现类重名而发生覆盖的情况,为了在使用它们的时候不让编译器混淆,我们给类加上一个限定 (前缀),把所有java程序保存在各自的目录里面,而该目录就是包,包的本质实际上就是一个文件夹。
- 将类放入包
导入类包需要使用import
关键字;我们导入类以后我们就不用使用完整的类名了,就可以直接找到该包下的该类。导如类包的语句要放到class的最上面。如果导入某一个包中的很多类名,我们可以通过*
来进行导入import java.util.*;
该包下的所有类。
a、使用import关键字导入静态成员
例如我们平时使用的System.out.println();
输出语句:
public class Demo{
public static void main(String[] args){
System.out.println();
}
}
我们可以通过:导入静态成员,然后下面可以直接使用out
即可
import static java.lang.System.out; //导入静态成员
public class Demo{
public static void mian(String[] args){
out.println();
}
}
b、可以通过使用Alt + /
来快速补全类以及进行导包。也可以使用Ctrl + Shift + o
即可快速导入该class需要导入的包。
2、访问包中的类
a、在同一个包中直接用类名来访问,不用指定类所在的包
如果两个代码都在同一个包中的话, 是不用使用import语句来调用的。 可以直接使用另一个主类,通过新建对象的方式使用类的方法等等。
public class A{undefined
public static void T(){undefined
System.out.print("这是A类的方法");
}
public void T2(){undefined
System.out.print("这是A类的非静态方法");
}
}
class B{undefined
static void T(){undefined
A.T();//调用A类的静态方法
A a=new A();
a.T2();//用A类的实例化对象调用非静态方法
}
}
b、两个类不在同一个包中的情况
首先import声明
import Form.TotalPage;
//import 调用的包名.类名;
然后在代码里调用
TotalPage.Totalpage();
//类名.调用的方法名
注意:
- 如果一个包中类很多,可以用“import包名.*”导入该包中所有类
- 包名中有“.”并不表示包中含有另一个包,而只是另一个包名的出现。
三、使用访问控制修饰符
1、类的访问控制修饰符
Java语言中类的访问权限控制符有public.protected.default.private四个,在定义类时,访问控制修饰符只能一个。每个Java程序的主类都必须是public类,主类必须具有文件名称相同的名字。
2、成员的访问控制修饰符
四、使用类中类
1、类中类的作用:
a.内部类提供了更好的封装性
b.内部类可以直接访问外部类的私有成员
c.外部类不能直接访问内部类的成员
d.匿名内部类适合用于创建一次性使用的类
注意:
内部类中的成员只在内部类范围内才能使用,外部类不能像使用自己的成员变量一样使用他们。