Java protected的理解

protected受访问保护规则是很微妙的。

  虽然protected域对所有子类都可见。但是有一点很重要,子类只能在自己的作用范围内访问自己继承的那个父类protected域,该子类无法到访问别的子类(同父类的亲兄弟)所继承的protected域。

  

  protected的可见性在于两点:

  1. 基类(父类)的protected成员是包内可见的,并且对子类可见;
  2. 若子类与基类不在同一包中,那么在子类中,子类实例可以访问其从基类继承而来的protected方法,而不能访问基类实例的protected方法。


   final:表示此方法已经是“最后的、最终的”含义,亦即此方法不能被重写和引用变量被final修饰之后,不能再指向其他对象(其指向的对象的内容是可变的),能被重新定义

  static:修饰变量和内部类(不能修饰常规类),其中所修饰变量称为类变量或静态变量。静态变量是和类层次的变量,每个实例共享这个静态变量,在类加载时初始化。

  default:即不加任何访问修饰符,通常称为“默认访问模式“。该模式下,只允许在同一个包中进行访问。

  abstract:修饰类和方法。当修饰类时,该类不能创建对象;修饰方法时,为抽象方法。类只要有一个abstract方法,类就必须定义为abstract,但abstract类不一定非要有abstract方法不可。


  final:

    被声明为final的变量必须在声明时给定初值(当然,空白final可以延迟到构造器中赋值),而且被修饰的变量不能修改值。

    当修饰类时,该类不能派生出子类;修饰方法时,该方法不能被子类覆盖。

    表示此方法已经是“最后的、最终的”含义,亦即此方法不能被重写和引用变量被final修饰之后,不能再指向其他对象其指向的对象的内容可变),能被重新定义

    两种初始化方式,一种是在变量声明的时候初始化;第二种方法是在声明变量的时候不赋初值,但是要在这个变量所在的类的所有的构造函数中对这个变量赋初值。

public class Test { 
    public static void main(String[] args)  { 
        final MyClass myClass = new MyClass(); 
        引用变量被final修饰
        System.out.println(++myClass.i); 
        指向的对象的内容可变
    } 
} 
class MyClass { 
    public int i = 0; 
}
public class B extends A {
    public static void main(String[] args) {}
    public void getName() {}
}

class A {
    因为private修饰,子类中不能继承到此方法,因此,子类中的getName方法是重新定义的、属于子类本身的方法,编译正常(可被重新定义)
   private final void getName() {}

    因为public修饰,子类可以继承到此方法,导致重写了父类的final方法,编译出错(不能被重写)
    public final void getName() {}
}

    参数i用final修饰之后,就不能在方法中更改变量i的值了。

    值得注意的一点,方法changeValue和main方法中的变量i根本就不是一个变量,因为java参数传递采用的是值传递,对于基本类型的变量,相当于直接将变量进行了拷贝。

    所以即使没有final修饰的情况下,在方法内部改变了变量i的值也不会影响方法外的i。

public class TestFinal {
    public static void main(String[] args){
        TestFinal testFinal = new TestFinal();
        int i = 0;
        testFinal.changeValue(i);
        System.out.println(i);  
    }
    public void changeValue(final int i){
        //final参数不可改变
        //i++;
        System.out.println(i);
    }
}

 

posted @ 2020-04-21 14:15  hugeba  阅读(2193)  评论(0)    收藏  举报