JAVA篇:修饰符与接口、类、方法、成员变量、局部变量、方法块
或许这是一个比较轻松简单的知识点,因为只是简单地做一个总览对比而已。这周比较忙,祝我自己好运。
有关接口(interface)的修饰符,其实一般用public,也可以不加修饰词(default),或者是使用private修饰的声明在类的内部的内部接口。不存在protected修饰的接口。而接口内部可以有用public static final修饰的静态常量,除此之外只存在public修饰的方法(接口中无修饰词的方法也默认是public)了。无论是接口还是接口中的方法的abstract修饰词都是隐含的,不必显式地修饰在接口或者方法前面。
1、接口(interface)
在java中,接口是一个抽象类型,是抽象方法的集合,接口通常以interface来声明,接口只能包含抽象方法和以static\final修饰的变量,一个接口可以继承(extends)另一个接口。
接口只包含要实现的方法,而类描述对象的属性和方法,两者实现类似但是概念不同。java提供了类和接口之间的实现机制,接口不可被实例化,只能被实现(implements),实现接口的类必须实现接口中全部的抽象方法,否则该类必须使用abstract声明为抽象类。
接口之间支持多继承,一个类也可以实现多个接口。存在一种特殊的接口--标记接口,不包含任何属性和方法,仅仅用于继承。
接口不可实例化,但是可以定义接口变量,指向实现该指针的类的实例。
修饰符:
1) 接口和接口内方法都是隐式抽象的,不需要加abstract关键字
2) 接口可以是public修饰或者默认缺省(default)
3) 接口中的方法默认并且只能是public
4)接口中定义的变量默认并且只能是public static final 型,且必须给其初值,所以实现类中不能重新定义,也不能改变其值
5) 有用private修饰的接口,属于类的内嵌接口,但是私有接口的方法和变量也必须是public修饰的
2、类(Class)
类描述对象的属性和方法,一个类可以实现多个接口,但是类之间不支持多继承。
类之中包含类的成员变量、方法、构造方法、方法中的局部变量、方法块。
其中,局部变量包含在方法、构造方法、部分方法块中。方法块分为普通方法块、构造方法块、静态方法块。普通方法块位于方法之中,在方法被调用时运行。构造方法块与构造函数同级,可运行多个构造函数相同的部分,在构造实例时候运行。静态方法块使用static修饰,一般进行静态变量的赋值,在类加载初始化阶段运行。
2.1 修饰符
public:可修饰类、成员变量、构造方法、方法。
protected:可修饰成员变量、构造方法、方法。
default(缺省、friendly):可修饰类、成员变量、构造方法、方法。
private:可修饰类、成员变量、构造方法、方法。
static,:可修饰成员变量、方法、方法块。
final:可修饰类、成员变量、方法、局部变量。
abstract:可修饰类、方法。
transient(暂时的), volatie(易失的):修饰成员变量
native:修饰方法
synchronized(同步的):修饰方法和方法块
2.2 修饰符与继承:
2.2.1 public,protected,default(缺省、friendly),private
public是指公共的,不限制访问和继承、重写。
protected:是指受保护的,修饰成员变量、构造方法、方法,只能本包和子类访问。可以被继承、重写。
default(缺省、friendly):限制只能本包访问。不可被继承。
private:是指私有的,只可在类中的方法访问,不可被继承,不可被外部调用。私有类必须定义在类的内部。私有的构造方法一般有特殊用途,如单例模式。
注:这里的访问权限并不涉及反射机制相关的访问问题,而且,若是公共方法调用私有变量这种过程可以分解为:外部调用类的公共方法,类内部的公共方法调用私有变量,并不违背修饰符的访问限制。
2.2.2 static(静态的)和 final (不可改变的)
static修饰的成员变量、方法、方法块和类绑定而不是和类的实例绑定。而static修饰的变量、方法可以被继承,不可以被重写。若是在子类实现了同名的方法,那也只是子类的方法,而不是将继承自父类的方法重写,变量绑定时,父类变量只会调用父类的静态方法,具体如下:
/* 被实现的接口、抽象类以及被继承的父类的变量可以指向子类的实例,但是“成员变量,静态方法看左边;非静态方法:编译看左边,运行看右边。” */ FClass f = new CClass();//CClass是FClass的子类 /* 那么f指向的对象: 1、静态方法、变量:编译和运行的都是FClass的静态方法、静态变量 2、非静态方法、变量:编译的是看父类FClass,父类有的方法、变量,f指向的对象才会有, 运行的时候看的是子类CClass,子类若是对父类的该方法进行了重写,就按重写之后运行 */
而final修饰的类不可被继承,final修饰的变量和方法不可更改,final修饰的变量可被继承可在子类中重新赋值,final修饰的方法可被继承但不可重写,会报错。
父类:
class FClass{ public static int fval = 1; public int fval2 = 1; public final int fval3 = 1; public static void P(){ System.out.print("Static FClass:"); System.out.println(fval); } public void P2(){ System.out.print("FClass:"); System.out.print(fval2); System.out.print(" final: "); System.out.println(fval3); } public final void P3(){ System.out.print("final FClass:"); System.out.println(fval3); } }
子类:
class CClass extends FClass{ public static int fval = 2; public int fval2 = 2; public final int fval3 = 2; public static void P(){ System.out.print("Static CClass:"); System.out.println(fval); } public void P2(){ System.out.print("CClass:"); System.out.print(fval2); System.out.print(" final: "); System.out.println(fval3); } /**报错 public final void P3(){ System.out.print("final CClass:"); System.out.println(fval3); }*/ }
结果:
FClass fclass = new CClass(); fclass.P();//输出:Static FClass:1 fclass.P2();//输出:CClass:2 final: 2-final修饰的变量是子类中设置的值 fclass.P3();//输出:final FClass:1 CClass cclass = new CClass(); cclass.P();//输出:Static CClass:2 cclass.P2();//CClass:2 final: 2 cclass.P3();//final FClass:1---因为子类中重写报错,直接调用的继承自父类的方法,final的值也是父类的值
2.2.3 abstract(抽象的)
抽象类是指使用abstract修饰的类,一般情况下会包含至少一个抽象方法,不能实例化,通常用来进行继承,但是类之间不支持多继承。
抽象类是类,对比接口,抽象类的性质和实现跟类相似,只是一般会有一个由abstract修饰的方法。
2.2.4 native(本地的)
native修饰的方法修饰的方法是一个原生态的方法,其实现不在本文件,而是在用其他语言实现的文件之中。java语言本身不能对操作系统底层进行操作和访问,但是可以通过JNI接口调用其他语言来实现对操作系统的操作。有关JNI(Java Native Interface)后面再进行具体了解。
2.2.5 transient(暂时的)
序列化的对象包含被transient修饰的实例变量时,java虚拟机(JVM)跳过该特定的变量。该修饰符包含在定义变量的语句中,用来预处理类和变量的数据类型。
2.2.6 volatie(易失的)
volatile修饰的成员变量在每次被线程访问时,都强迫从共享内存中重读该成员变量的值。而且,当成员变量发生变化时,强迫线程将变化值回写到共享内存。这样在任何时刻,两个不同的线程总是看到某个成员变量的同一个值。一个volatile对象引用可能是null。
volatile一般配合synchronized进行多线程开发。
2.2.7 native(本地的)
JNI
2.2.8 synchronized(同步的)