Java修饰词

一到学校感觉写点博客随笔的时间和机会就少了,最近开了Java课程,趁着线上金工实习啥也不想听还不如写点笔记,毕竟逸一时,误一世捏。

首先学过的都知道,Java是一种面向对象编程(OOP)的程序语言,那么它必然满足OOP的三个特征:封装性,继承性,多态性。这些特性在上个学期的C++的面向对象的学习中已经了解不少,这些便不必多言,这篇随笔主要是为了总结一下Java中的一些在之前的学习中不怎么熟悉的修饰词。

修饰词在Java中用于修饰类(Class),方法,以及变量,主要分为两种,即访问修饰符和非访问控制符:

访问控制符:

在Java中,访问控制符主要用于对类,方法和变量的访问控制的保护,共有四种不同的访问控制:

• Default--默认控制符

表示该方法或变量在同一包内可被访问,可适用于方法与类,不能用于修饰类(外部类)。

• Private--私有控制符

表示该方法或变量在同一类中可被访问,适用于变量与方法,不能用于修饰类(外部类)。

是最严格的访问控制,被声明为私有访问的变量与方法只能在类内被调用,且外部类与接口不能被声明为私有。

• Public--公有控制符

表示对所有类都可见,适用于类,方法,变量。

纯纯的共有,一眼丁真。 

• Protected--保护控制符

表示对同一包内的类与子类可见,适用于变量与方法,不能用于修饰类(外部类)。

受保护的访问修饰符是实践中常用的修饰符,尽管它比前几个都麻烦🤢:

麻烦主要就麻烦在子类与基类的继承调用关系中,子类与基类不在同一个包时,子类只能访问从基类继承而来的protected方法而不能访问基类实例的protected方法;子类与基类在同一个包时,子类能随意访问基类的protected方法与变量。

那它的作用在于何处?倘若一个父类中的某方法声明为private,那么除了该父类其他的类无论是否子类都无法访问这个方法;再者如果这个方法被声明为public,那所有的类也无论是否子类都能访问这个方法。这相当于两个极端,但如果适时地选择protected来声明这个方法,便可以达到“只有子类能访问”绝佳领域,有效保护被声明的类或方法或变量不被随意调用或访问。

 

非访问控制符:

非访问控制符主要也是用来修饰类,方法以及变量,只是它们达成的目的各有不同:

• static修饰符

static用来修饰类方法与类变量,表明声明了一个静态类/变量。

静态是什么意思?这个我去年学C++时就没整明白,查了很多资料还是一头雾水,正好趁这个机会再学一遍:

• 首先对于静态变量,最形象的表达就是插个代码,这个代码概念是我学C++时就试图理解过的,把它翻译为java的样式再看一遍:

 1 package test_static;
 2 
 3 public class test01 {
 4     public static int a = 0;
 5     public int b = 0;
 6 
 7     public static void main(String[] args) {
 8         //声明一个test01的类
 9         test01 t1 = new test01();
10         System.out.println("t1.a=" + t1.a);
11         System.out.println("test01.a=" + test01.a);
12         System.out.println("t1.b=" + t1.b);
13         //分别加1来观察变化
14         t1.a++;
15         t1.b++;
16         System.out.println();
17 
18         test01 t2 = new test01();
19         System.out.println("t2.a=" + t2.a);
20         System.out.println("test01.a=" + test01.a);
21         System.out.println("t2.b=" + t2.b);
22 
23 
24     }
25 }
CanCanWord

运行结果是这样的:

t1.a=0
test01=0
t1.b=0

t2.a=1
test01=1
t2.b=0

很显然的变化--在a的数值上,对于我来说最浅显的理解就是a这个变量在声明为static后成为了一个优先级很高的一个变量,高于在main类中实例化的类中的其他变量,对无论是t1.a还是t2.a的访问或改变最后都会指向同一个更高层的a

 

当然上面那些都我自己的胡扯以及臆想,实际上应该更官方更学术地解释为:类中声明了一个静态变量,JVM只为其分配一个内存,你在任何实例化的对象中对这个变量的访问都会引导至这个地址,这个内存。可以用类名直接访问,因为无论如何你访问的都是一个东西,也可以用对象名.变量访问,但不推荐,我写时候就直接给我提示错误了

 

查了查阿里巴巴java规约,里面有这么一句话:调用一个类的静态方法或变量,直接使用类名调用,不要使用类的实例来调用,会增加编译成本

 原来如此。

• 然后对于静态方法,也同样类似于静态变量,注意点在于静态变量首先是不能使用this以及super关键字的,也不能调用非静态的变量,他只能访问所属类的其他静态变量与成员方法。以上的这些注意事项的首要原因就是,非静态的方法与变量在类的具体对象还未生成时就已经创建了,未生成也就表达着非静态的变量和方法也许还没有生成,也就没有访问一说了。


 

说到现在,用一句浅显或有些片面的话来讲,静态和之前所了解的全局有些类似,但实际有一点是,之前在学习所谓全局变量C++时大多数都是在一份源代码中考虑实践,而全局与静态的最大区别就是在作用域中,放到现在的几份代码共同存在与包中考虑,这样一来作用域就必须纳入考虑范围了,如果程序包含多个文件的话,静态变量作用于定义它的文件里,不能作用到其他文件里,即被static关键字修饰过的变量具有文件作用域。这样即使两个不同的源文件都定义了相同的静态全局变量,他们也是不同的变量。

• final修饰符

final 表示"最后的、最终的"含义,变量\方法一旦赋值\编写后,不能被重新赋值\重写。被 final 修饰的实例变量必须显式指定初始值,用final修饰过的方法在赋值后可被子类继承但无法被子类修改,这样就能防止该方法的内容被修改。而如果是final类,那它将无法被其它类继承。

• abstract修饰符

abstract可以用来修饰类,方法;其在修饰类时其实并没有什么太大的意义,主要是为了之后在创建的抽象类里写抽象方法做好前提,但值得一说的是抽象类是无法实例化对象的,它只能是为了做扩充而存在的。接着是抽象方法,抽象修饰符修饰的方法在抽象类中并没有实体,它只是一个框架,具体的实现还需要子类来创建,同时抽象类的子类还必须得把父类(抽象类)中的所有抽象方法都给一个具体的实现。

比如你声明一个Animal的抽象类,里边有Eat方法与Sleep方法,那么之后创建的子类Cat中必须将Animal类中的抽象方法都按自己的需求重写一遍,另一个子类Dog也必须按自己的需求也把那些抽象方法重写一遍,两个子类的需求不同,也就有各自不同的重写方法,如下:

 1 //创建一个Animal抽象类
 2 public abstract class Animal {
 3     public abstract void eat();
 4     public abstract void sleep(); 
 5 }
 6 
 7 //创建一个Cat子类
 8 public class Cat extends Animal {
 9     private static String name="Haha";
10     //重写了抽象父类的eat()方法
11     public void eat() {
12         System.out.println("Cat is eating!");
13     }
14     //重写了抽象父类的sleep()方法
15     public void sleep() {
16         System.out.println("Cat is sleeping!");
17     }
18     //随便写个不是父类里的方法        
19     public void jump(){
20         System.out.println("Cat is jumping!");
21     }
22 }
23 
24 //创建一个Dog子类
25 public class Dog extends Animal {
26     private static String name="Lala";
27     //重写了抽象父类的eat()方法    
28     public void eat() {
29         System.out.println("Dog is eating!");
30     }
31     //重写了抽象父类的sleep()方法
32     public void sleep() {
33         System.out.println("Dog is sleeping!");
34     }
35     //随便写个不是父类里的方法 
36     public void swim(){
37         System.out.println("Dog is swimming");
38     }
39 }
40 
41 //测试代码
42 public class test {
43     public static void main(String[] args) {
44         Cat cat = new Cat();
45         Dog dog = new Dog();
46         cat.eat();
47         dog.eat();
48         cat.sleep();
49         dog.sleep();
50         cat.jump();
51         dog.swim();
52     }
53 }
CanCanWord

结果想必会是很明显的

Cat is eating!
Dog is eating!
Cat is sleeping!
Dog is sleeping!
Cat is jumping!
Dog is swimming

这样对它的用法应该就一目了然了。

 

后记

其余的还有很多关于线程的修饰符,但还没学到,没办法,有时间学了线程再回来补完吧,先这样吧🐱‍🚀

 

posted on 2022-10-07 15:07  Project_163  阅读(114)  评论(0)    收藏  举报

导航