概述
本文主要介绍JAVA的一些比较难以理解的关键字和用法
protected 关键字
protected定义
> 顾明思议,因为受保护,但是保护的范围是有限的,可以保护所处的包,子类和自己.限制了使用范围.
> 如果希望超类中的某些方法允许被子类访问,或者允许子类的方法访问超类的某个域,为此需要将这些方法或域设置为protected。
在实际的程序中很实用这个关键字。
protected 使用
public class protect {
private String name;
protected int age;//可供子类使用
public protect(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "protect [name=" + name + ", age=" + age + "]";
}
}
public class protectChild extends protect{
private String major;
public protectChild(String name, int age,String major) {
super(name, age);//使用超类的构造方法,
this.major = major;
}
public String getMajor() {
return major;
}
public void setMajor(String major) {
this.major = major;
}
@Override
public String toString() {
return "protectChild [major=" + major + "]" +"[age=" + age +"]" ;
}
}
结果为:
> 1
> protect \[name=gaga, age=20\]
> 20
> protectChild \[major=chinese\]\[age=40\]
上面的代码中我们可以看到,在子类中可以直接访问超类中的protected域。
在本包中的其他类也可以直接访问,但是注意到一点,
子类和调用该类的其他类可以直接访问该保护类型的变量对进行修改。
public class Protext {
public static void main(String[] args) {
protect p = new protect();
System.out.println(p.age);
p.age = 10;
System.out.println(p.age);
}
}
结果为:
> 1
> 10
可以看到超类中的age值已经被更改为10了.
abstract 关键字
abstract定义
何为抽象,比如车可以有很多种车,实际使用时并不确定要用哪种车,只有使用的时候才确定,车可以run,如何run? 汽车路上run,飞车天上run,水车水里run。
no matter 车如何run,只有run的时候才知道,所以车是一个抽象的,run的方式也是一个抽象的,于是一个包含抽象方法的抽象类则可以这样定义:
public abstract Car{ //抽象类
public abstract run();//抽象方法,抽象方法又子类实现,抽象方法只定义
}
abstract 使用
public abstract class Car {
private String name;
Car(){
System.out.println("抽象方法无参构造函数");
}
Car(String name){
System.out.println("父类已经实例化");
this.name = name;
System.out.println(name);
}
public void mothod1(){
System.out.println(this.getClass());
System.out.println("抽象类的实例方法");
}
public abstract void mothod2();//抽象方法2
public abstract void method3();//抽象方法3
}
class Bicycle extends Car{
public Bicycle(String name) {
super(name);
System.out.println("子类已经实例化");
}
@Override
public void mothod2() {//需要覆写抽象方法mothod2
}
@Override
public void method3() {//需要覆写抽象方法mothod3
}
public static void main(String args[]){
Car car = new Bicycle("山地自行车")
}
}
结果为:
> 父类已经实例化
> 山地自行车
> 子类已经实例化
abstract注意事项
> 1:抽象方法只能定义在抽象类中,抽象类和抽象方法必须由abstract关键字修饰.
> 2:抽象方法只定义方法声明,并不定义方法实现,没有{}.
> 3:抽象类不可以被创建对象(实例化)。
> 4:只有通过子类继承抽象类并覆盖了抽象类中的**所有**抽象方法后,该子类才可以实例化。否则,该子类还是一个抽象类,没有实际意义。
> 5:抽象类与interface有很大的不同之处,接口中不能有实例方法去实现业务逻辑,而抽象类中可以有实例方法,并实现业务逻辑,比如我们可以在抽象类中创建和销毁一个线程池.
> 6:抽象类不可被**static,private,final**修饰,原因分别为abstract修饰的类不可实例化,需要子类实现,需要被继承。
> 7:抽象类其实是可以实例化的,但是他的实例化方式不是通过new方式来创建对象,而是通过父类的引用来指向子类的实例来间接地实现父类的实例化(因为子类要实例化前,一定会先实例化他的父类。这样创建了继承抽象类的子类的对象,也就把其父类(抽象类)给实例化了)
final 关键字
final 定义
> final 最终的,不可变的,用来修饰类,属性,变量等.
> 无论属性是基本类型还是引用类型,final所起的作用都是变量里面存放的**值**不能变,这个值,对于基本类型来说,变量里面放的就是实实在在的值,如110,“abc”等。
> 而引用类型变量里面放的是个地址,所以用final修饰引用类型变量指的是它里面的**地址**不能变,**并不是**说这个地址所指向的对象或数组的内容不可以变,这个一定要注意。
public void test(){
final Person p = new Person("name"); //那么你不能对p进行重新赋值,但是...
p.setName('newName'); //你可以改变p里面属性的值,因为P对于的地址是不变的,但是地址所指向的对象内容是可变的
}
final 注意事项
> 1. final修饰属性,声明变量时可以不赋值,而且一旦赋值就不能被修改了。
> 对final属性可以在三个地方赋值:声明时、初始化块中、构造方法中,总之一定要赋值。
> 2. final修饰类中的方法, 作用:可以被继承,但继承后不能被重写。
> 3. final修饰类, 作用:类不可以被继承。
byte做加法失败问题
public void sumByte(){
byte b1=1;
byte b2=3;
byte b3=b1+b2;// 当程序执行到这一行的时候会出错。
// 因为b1、b2可以自动转换成int类型的变量,运算时java虚拟机对它进行了转换,结果导致把一个int赋值给byte-----出错
}
public void sumByte(){
//将b1 b2加上final修饰后
final byte b1=1;
final byte b2=3;
byte b3 = b1+b2;// 不会出错,因为基础类型被final修饰后其值不再改变,也就不会对b1,b2进行自动int提升,则不会出错。
}
STATIC 关键字
定义
表明具有静态属性,用来申明类的属性和方法.
注意事项
> 1. static变量:变量分类,一种是被static修饰的变量,叫静态变量(类变量);
> 另一种是没有被static修饰的变量,叫实例变量。
> 对于静态变量在内存中只会一次拷贝(节省内存),JVM只为静态分配一次内存,
> 在加载类的过程中优先加载完成静态变量的内存分配,可用类名直接访问(方便),
> 当然也可以通过对象来访问(但是这是不推荐的)。
> 2. 对于实例变量,没创建一个实例,就会为实例变量分配一次内存,
> 实例变量可以在内存中有多个拷贝,互不影响(灵活)。
> 3. static代码块:static代码块是类加载时,初始化自动执行的,其优先级仅次于静态变量。
> 如果static代码块有多个,JVM将按照它们在类中出现的先后顺序依次执行它们,每个代码块只会被执行一次。
> 4. static方法:static方法可以直接通过类名调用,任何的实例也都可以调用,因此static方法中不能用this和super关键字。
> 不能直接访问所属类的实例变量和实例方法(也就是不带static的成员变量和成员成员方法)。
> 只能访问所属类的静态成员变量和成员方法。
> 因为static方法独立于任何实例,因此static方法必须被实现,而不能是抽象的abstract。
> static方法只能访问static的变量和方法,因为非static的变量和方法是需要创建一个对象实例才能访问的,而static的变量/方法不需要创建任何对象。
总结
了解Java关键字的用法和含义在设计代码时候非常有用。