权限修饰符,内部类,匿名内部类
权限修饰符:
public:
public是权限最大的修饰符,他可以修饰类,成员变量,成员方法,构造方法。
被public修饰后,可以再任何一个类中,不管同不同包(同一类、同一个包的子类、同一包其他类、不同包子类、不同包其他类都可以调用),任意被调用。
protected:
protected可以修饰成员变量,成员方法,构造方法,但不能修饰类(此处指的是外部类,内部类不加以考虑)。
被protected修饰后,只能被同包下的其他类访问。如果不同包下的类要访问被protected修饰的成员,这个类必须是其子类( 同一类 同一包子类 同一包其他类 不同包的子类)。
默认(即什么都不加):
它可以修饰类,成员变量,成员方法,构造方法。
默认权限修饰后,其只能被本类以及同包下的其他类访问(同一类 同一包子类 同一个包的其他类)。
private:
private可以修饰成员变量,成员方法,构造方法,不能修饰类(此刻指的是外部类,内部类不加以考虑)。
被private修饰的成员只能在其修饰的本类中访问,在其他类中不能调用,但是被private修饰的成员可以通过set和get方法向外界提供访问方式。
类可以使用 public 和默认修饰符修饰
内部类:
成员内部类:
-
定义在当前类中,可以被当前类作为属性调用
-
内部类可以作为当前类的属性被调用,用外部类.内部类的形式
-
内部类存在构造方法,可以创建对象
-
内部类可以直接访问外部类的成员,包括私有
-
外部类要访问内部类的成员,必须要创建对象
-
内部类不能直接new内部类对象,因为内部类没被static修饰,所以内部类属于对象,要想创建内部类对象需要先构建外部类的对象,通过外部类对象创建内部类的对象。
构建没有static修饰的内部类对象:
内部类名 变量名 = new 外部类名.new 内部类名();
例如:InnerClass innerClass = new Outer().new InnerClass();
构建有static修饰的内部类(静态内部类):有static修饰的内部类属于类,可以直接使用外部类.内部类的形似创建对象。
内部类名 变量名 = new 外部类.内部类名();
例如:InnerStaticClass innerStaticClass = new Outer.InnerStaticClass();
内部类的使用场景:Spark源码
当一个类的构造方法被private修饰时,可以使用内部类调用其构造方法
public class MySpark {
String SparkContext;
public void getModel(){
System.out.println("当前模式:"+SparkContext);
}
private MySpark(String sparkContext) {
SparkContext = sparkContext;
}
static class Builder{
String master;
public static MySpark builder(String master){
if (master.equals("local")){
return new MySpark("local SparkContext");
}else {
return new MySpark("cluster");
}
}
}
}
public class Test{
public static void main(String[] args) {
MySpark master = MySpark.Builder.builder("local");
master.getModel();
}
}
局部内部类:
定义在成员方法内部,随着成员方法的使用而消亡
必须被final修饰,因为局部变量会随着方法的调用完毕而消失,这个时候,局部对象并没有立马从堆内存中消失,还要使用那个变量。为了让数据还能继续被使用,就用fianl修饰,这样,在堆内存里面存储的其实是一个常量值。
匿名内部类:
前提:存在一个类(具体类或抽象类)或者接口
格式:
new 类名或者接口名() {重写方法;}
本质:是一个继承了类或者实现了接口的子类匿名对象
例如有个接口:English
public interface English {
public void sayHello(String word);
}
有一个Student实现了English接口
public class Student implements English{
@Override
public void sayHello(String word) {
if (word.equals("hello")) {
System.out.println("hello");
}else {
System.out.println("bye");
}
}
}
有一个调用类
public class UseEnglish {
//一个使用类(具体类或抽象类)或者接口的函数
public static void useEnglish(English english,String word){
english.sayHello(word);
}
public static void main(String[] args) {
//原本可以写成
/*Student student = new Student();
useEnglish(student,"hello");
*/
//用内部类可以写为:
useEnglish(
//并不是直接创建一个接口的对象,而是在java执行时创建一个匿名内部类。并构建其对象作为一个参数传入参数列表
new English() {
@Override
public void sayHello(String word) {
if (word.equals("hello")) {
System.out.println("hello");
}else {
System.out.println("bye");
}
}
},"hello");
.println(“hello”);
}else {
System.out.println(“bye”);
}
}
},"hello");