1.static(静态的;属于类而不属于对象)
①被static修饰的对象不再属于具体的某个对象,而是属于类。
②当前类所创建的对象都共享这个static所修饰的对象。
③静态对象是在类加载的时候进行初始化的,仅仅加载一次,且优先于对象存在的。
④静态对象在内存中只存在一份,所用对象共享此属性,其中一个对象对其进行修改,所有对象都会被修改。
1)修饰属性
修饰属性,为静态属性,属于类,不属于某个对象,可以通过类名直接调用静态属性,对象也可以进行调用
package Review.KeyWord;
public class keyWordStatic {
private static String color; // 静态属性
private int size;
public static String getColor() {
return color;
}
public static void setColor(String color) {
keyWordStatic.color = color;
}
public int getSize() {
return size;
}
public void setSize(int size) {
this.size = size;
}
}
测试类1:
package Review.KeyWord;
public class keyWordStaticTest {
public static void main(String[] args) {
keyWordStatic kws = new keyWordStatic();
keyWordStatic kws1 = new keyWordStatic();
kws.setColor("red");
kws.setSize(5);
System.out.println(kws.getColor());
System.out.println(kws.getSize());
System.out.println("-------分割线--------");
kws1.setColor("green");
kws1.setSize(7);
System.out.println(kws1.getColor());
System.out.println(kws1.getSize());
}
}
运行结果:
red
5
-------分割线--------
green
7
测试类2:
package Review.KeyWord;
public class keyWordStaticTest {
public static void main(String[] args) {
keyWordStatic kws = new keyWordStatic();
keyWordStatic kws1 = new keyWordStatic();
kws.setColor("red");
kws.setSize(5);
kws1.setColor("green");
kws1.setSize(7);
System.out.println(kws.getColor());
System.out.println(kws.getSize());
System.out.println("-------分割线--------");
System.out.println(kws1.getColor());
System.out.println(kws1.getSize());
}
}
运行结果:
green
5
-------分割线--------
green
7
从上面两个测试类中,可以发现属性color被定义为静态的,而size则是中规中矩的一般属性。在测试类1中,在给两个属性初始化之后分别打印输出,没有任何影响;但是到了测试类2中,小编先给两个属性初始化,再打印输出,可以发现运行结果不一致。
换言之,当普通属性被static修饰时就成了静态属性,从而它就不再属于对象而是属于类,且只要对象调用时候对其进行再一次地初始化,其所有调用的它的对象的值都会被改变。需要注意的是:静态属性和静态方法可以通过其类名对其直接进行调用。
2)修饰方法
修饰方法,为静态方法,静态方法只能调用静态方法和属性而不能调用非静态方法和属性;但是非静态方法两者都可以调用。这是为什么呢?因为静态方法是属于类的,而非静态方法是属于对象的。在编译过程中,静态方法是优先于非静态方法而存在的。
另外需要注意的是:静态方法可以被重载,但是它没有多态。
思考一个问题:静态方法中能否使用this,super关键字?为什么?
在静态方法中不能使用this,super关键字
原因:
①静态(属性、方法)属于类,this、super属于当前对象,静态优先于对象存在。
②无需本类的对象即可调用静态方法即意味着静态方法中不需要this、super关键字。(即静态方法可以通过类名直接进行调用)
③静态方法是存放在内存中的数据段中,而this、super是heap堆中的引用,不能对数据段中的数据进行调用。
④静态方法属于类,不属于任何一个对象,是所有对象共享使用的,而this代表单个对象。
3)修饰代码块
静态代码块随着类加载初始化代码块中的内容只初始化一次。
在多层次继承关系中,普通属性、静态属性、普通方法、静态属性、构造方法、代码块、静态代码块的加载顺序是怎样的?
加载顺序:
父类的静态对象(按定义顺序)
子类的静态对象(按定义顺序)
父类的普通对象(按定义顺序)
父类的构造方法
子类的普通对象(按定义顺序)
子类的构造方法
补充:静态总是优先于普通而加载的
2.abstract(抽象的)
1)修饰类
①修饰类时当前类为抽象类,该类不能被直接实例化(创建对象)
②一般修饰的是父类(父类只是对子类功能的统一定义)
③通过多态的方式来创建抽象类的对象
上图中,Phone是一个抽象类,如果这样去对其创建对象,在IDE中就会报错。所以不能对一个抽象类进行直接实例化。
package Review.KeyWord;
public class PhoneTest {
public static void main(String[] args) {
Phone p = new cellPhone(); // 通过多态方式对抽象类进行实例化
}
}
2)修饰方法
①修饰方法为抽象方法,抽象方法只有方法的声明,没有方法的实现(方法体)
②含有抽象方法的类一定是抽象类,抽象类中不一定含有抽象方法
③一个类继承一个抽象类要么实现(重写)抽象类中的所有抽象方法,要么将自己也声明为抽象类
父类:
package Review.KeyWord;
public abstract class Phone {
public void call() {
System.out.println("Phone----call");
}
abstract void makePhotography();
}
子类:
package Review.KeyWord;
public class cellPhone extends Phone{
@Override
void makePhotography() {
System.out.println("cellPhone---makePhotography");
}
}
从上面Demo中,继承一个抽象类要重写父类中所有的抽象方法,如果不需要重写所有抽象方法,那么只能将子类也声明为抽象类。
作用:
①一个类不想被创建对象,则可声明为抽象类
②不同子类的相同行为(功能)拥有不同的实现,则父类可定义为抽象类,方法可定义为抽象方法
③给子类特定的功能让子类去实现
问题:
①父类中所定义的功能方法是所有子类继承并需要重写,此时父类方法可定义为抽象方法。
②父类中所定义的功能方法是所有子类直接继承使用无需重写,此时父类方法可定义为普通方法。
另外,在抽象类中既可以定义抽象方法,又可以定义普通方法,分类不明确
3.final(最终不可改变的)
1)修饰变量
final修饰的变量为常量,必须要对其进行初始化(显示赋值、构造方法赋值),常量值不允许被修改,final可以修饰局部变量,修饰对象时是指对象的引用地址不可改变,和属性值无关
static和final关键字一起使用的好处
被static和final共同修饰的变量为静态常量。