Java——三个修饰符

1 static

static 修饰符也被称为静态修饰符。这个修饰符能够修饰三种程序组件:属性、方法、初始化代码块

1.1 静态属性

static 修饰属性,则该属性就成为静态属性。静态属性是全类公有的属性。

class MyValue{
    int a;
    static int b;
}
public class TestStatic{
    public static void main(String args[]){
    MyValue mv1 = new MyValue();
    MyValue mv2 = new MyValue();
    mv1.a = 100;
    mv1.b = 200;
    mv2.a = 300;
    mv2.b = 400;
    System.out.println(mv1.a);
    System.out.println(mv1.b);
    System.out.println(mv2.a);
    System.out.println(mv2.b);
    }
}

/*

100
400
300
400

*/

要注意,400 这个数字出现了两次,200 没有出现。原因在于:b 属性是一个静态属性。MyValue 类的所有对象,都公用一个 b 属性,每一个对象的 b 属性,都指向同一块内存。如下图所示:

 

1.2 静态方法

 

 

用 static 修饰的方法称之为静态方法

class TestStatic{
    int a = 10; //非静态属性
    static int b = 20; //静态属性
    public void ma(){} //非静态方法
    public static void mb(){} //静态方法
    public void fa(){ //fa 是一个非静态方法
    System.out.println(a); //非静态方法能够访问非静态属性
    System.out.println(b); //非静态方法能够访问静态属性
    ma(); //非静态方法中,能够调用非静态方法
    mb(); //非静态方法中,能够调用静态方法
}
public static void fb(){ //fb 是一个静态方法
    System.out.println(a); //编译错误 静态方法中不能访问非静态属性
    System.out.println(b); //静态方法中可以访问静态属性
    ma(); //编译错误, 静态方法中调用非静态方法
    mb(); //静态方法中可以调用静态方法
    }
}

在非静态方法中,无论方法或属性是否是静态的,都能够访问;而在静态方法中,只能访问静态属性和方法。静态方法和静态属性统称为静态成员。以上的规律可以记成:静态方法中只能访问静态成员需要注明的是,在静态方法中不能使用 this 关键字。除此之外,静态方法与静态属性一样,也能够用类名直接调用。

 

静态方法是属于全类公有的方法。从概念上来理解,调用静态方法时,并不针对某个特定的对象,这个方法是全类共同的方法。

class Super{
    public void m1(){
        System.out.println(“m1 in Super”);
    }
    public static void m2(){
        System.out.println(“m2 in Super”);
    }
}
class Sub1 extends Super{
    public void m1(){ //非静态方法覆盖非静态方法,编译通过
        System.out.println(“m1 in Sub”);
    }
    public static void m2(){ //静态方法覆盖静态方法,编译通过
        System.out.println(“m2 in Sub”);
    }
}
class Sub2 extends Super{
    public static void m1(){} // 静态方法覆盖非静态方法,编译出错!
    public void m2(){} // 非静态方法覆盖静态方法,编译出错!
}

静态方法只能被静态方法覆盖,非静态方法只能被非静态方法覆盖。

 

静态方法没有多态。当我们对一个引用调用静态方法的时候,等同于对这个引用的引用类型调用静态方法。

1.3 静态初始化代码块

public class MyClass{
    static {
    //此处为静态初始化代码块
       System.out.println(“In MyClass Static”);
    }
    int a;
    public MyClass(){
    System.out.println(“MyClass()”);
    }
}

1.3.1 类加载

类加载就是把.class 文件读入 JVM 的过程。也就是说,当 JVM 第一次遇到某个类时,会通过 CLASSPATH 找到相应的.class 文件,读入这个文件并把类的信息保存起来,这个过程叫做类加载。

 

2 final

final 属性能够修饰变量、方法和类。注意,所谓变量,既包括属性,又包括局部变量。也就是说,final 能够修饰属性、局部变量、方法参数(注意方法参数也是特殊的局部变量)。

2.1 常量

用 final 修饰的变量则称为常量。怎么来定义常量呢?可以把常量理解为:一旦赋值,其值不能改变的变量。

要注意的是,由于 static 属性是在类加载的时候分配空间的,因此静态的 final 属性不能在构造方法中赋值。我们可以选择在定义这个属性的时候赋值,或是在静态初始代码块中为这个属性赋值。

2.2 final 方法

相对 final 属性,final 方法的含义相对简单。final 修饰方法,表示该方法不能被子类覆盖。

2.3 final 类

final 修饰符也可以用来修饰类。final 类表示这个类不能被继承。

要注意区分 final 修饰方法和 final 修饰类的区别。一个类中有 final 方法,这个类能够被继承,但是无法覆盖 final 方法;而一个类如果本身就是 final 的,则这个类无法被继承,这样的话,它所有方法都无法被覆盖。

3 abstract

abstract 可以用来修饰类和方法。abstract 单词本身表示“抽象”,是 java 中一个很重要的修饰符。

3.1 抽象类

abstract 修饰类,则这个类就成为一个抽象类。抽象类的特点是:抽象类只能用来声明引用,不能用来创建对象。

虽然抽象类不能创建对象,但是抽象类能够声明引用,并让这个引用指向子类对象。从某种意义上说,写抽象类的目的就是为了能够让子类继承。

3.2 抽象方法

用 abstract 修饰的方法称为抽象方法。

抽象方法指的是:一个只有声明,没有实现的方法。对于抽象方法来说,方法的实现部分用一个分号来代替。

class MyAbstract{
    public abstract void m1();
    public void m2(){}
}

因此,如果一个类中有抽象方法,这个类就必须是抽象类。

abstract class MyAbstract{
    public abstract void m1();
    public void m2(){}
}

注意:有抽象方法的类必须是抽象类,但是反过来,抽象类中未必有抽象方法。

由此看出,抽象的语法和多态是紧密配合的。

总结一下:抽象方法的语法特征有如下几条:

1. 抽象方法只有声明,没有实现。实现的部分用分号表示。

2. 一个拥有抽象方法的类必须是抽象类。

3. 子类继承抽象类,要么也成为抽象类,要么就必须实现抽象类中的所有抽象方法。

3.3 抽象的作用

因此,使用抽象方法,就可以让我们把方法的声明放在父类中,把方法的实现留在子类中。这样一方面,能够很好的体现出“共性放在父类”这个基本的原则,另一方面,用父类类型的引用又可以调用这些方法,并不影响多态语法的正常使用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值