这一块的内容主要是有关 权限修饰符、内部类的概述。
权限修饰符
- 同一个类下:
public class PowerDemo1{
public String name = "张三";
protected int age = 21;
boolean flag = true;
private String id = "001";
public static void main(String[] args) {
PowerDemo1 powerDemo1 = new PowerDemo1();
System.out.println(powerDemo1.name);
System.out.println(powerDemo1.age);
System.out.println(powerDemo1.flag);
System.out.println(powerDemo1.id);
}
}
//张三
//21
//true
//001
- 同一个包子类、其他类
class Power{
public String name = "张三";
protected int age = 21;
boolean flag = true;
private String id = "001";
}
public class PowerDemo1{
public static void main(String[] args) {
Power power = new Power();
System.out.println(power.name);
System.out.println(power.age);
System.out.println(power.flag);
//Error:(18, 33) java: id可以在com.bigdata.shujia14.Power中访问private
// System.out.println(power.id);
}
}
//张三
//21
//true
- 不同包的子类
public class PowerTest1 extends PowerDemo1 {
public static void main(String[] args) {
PowerTest1 powerTest1 = new PowerTest1();
System.out.println(powerTest1.name); //public修饰的
System.out.println(powerTest1.age); //protected修饰的
}
}
//张三
//21
- 不同包的其他类
public class PowerTest1 extends PowerDemo1{
public static void main(String[] args) {
PowerDemo1 powerDemo1 = new PowerDemo1();
System.out.println(powerDemo1.name);//public修饰的
}
}
//张三
- 类及其成员修饰符
权限修饰符:private、默认的、protected、public
状态修饰符:static、final
抽象修饰符:abstract
类:
权限修饰符:默认的、public
状态修饰符:final
抽象修饰符:abstract
最常用的是public
成员变量:
权限修饰符:private、默认的、protected、public
状态修饰符:static、final
最常用的是public
构造方法:
权限修饰符:private、默认的、protected、public
最常用的是public
成员方法:
权限修饰符:private、默认的、protected、public
状态修饰符:static、final
抽象修饰符:abstract
最常用的是public
内部类
- 把类定义在其他类的内部,这个类就被称为内部类
举例:在类A中定义了一个类B,类B就是内部类 - 内部类的访问特点:
- 内部类可以访问外部类的成员,包括私有
- 外部类如果想要访问内部类的成员,就必须要创建对象
举例:
内部类Inner访问外部类Outer的变量,可以直接访问
外部类Outer访问内部类Inner的成员,需要创建对象,并由一个新的方法show2()调用
- 内部类的位置:
按照内部类在类中定义的位置不同,分为如下两种格式
- 成员位置(成员内部类)
- 局部位置(局部内部类)
成员位置、局部位置 举例:
- 成员内部类:
- 内部类可以访问外部类的成员,包括私有
- 如何创建对象呢
外部类名.内部类名 对象名 = new 外部类名.new 内部类名
class Outer3{
private int num = 20;
class Inner{
public void show(){
System.out.println(num);
}
}
}
public class InnerClassDemo3 {
public static void main(String[] args) {
//想要访问内部类的show()方法,就必须要创建Inner对象
// Inner inner = new Inner();
// inner.show();
//正确创建内部类对象的格式:
Outer3.Inner i = new Outer3().new Inner();
i.show();
}
}
//20
- 成员内部类常见修饰符:
private:为了保证数据的安全性
static:为了方便访问数据
注意事项:静态内部类访问的外部数据必须由静态修饰
class Outer4{
//局部变量
private int num = 10;
private static int num2 = 20;
//成员内部类被静态修饰 访问的局部变量也只能是静态的
public static class Inner4{
public void show(){
// System.out.println(num);
System.out.println(num2);
}
public static void show2(){
// System.out.println(num);
System.out.println(num2);
}
}
}
public class InnerClassDemo4 {
public static void main(String[] args) {
Outer4.Inner4 i = new Outer4.Inner4();
i.show();//20
i.show2();//20
//另一种创建内部类的方式,当成员变量被静态修饰后,访问的格式如下:
//外部类名.内部类名 对象名 = new 外部类名.内部类名()
Outer4.Inner4 i1 = new Outer4.Inner4();
i1.show();//20
i1.show2();//20
//调用show2()的另一种方式
Outer4.Inner4.show2();//20
}
}
一道小题目来加深理解外部类和内部类之间的一些小细节
在控制分别输出:30,20,10
class Outer {
public int num = 10;
class Inner {
public int num = 20;
public void show() {
int num = 30;
System.out.println(?);
System.out.println(??);
System.out.println(???);
}
}
}
- 注意:
- 内部类和外部类之间不存在继承关系,既然没有继承关系,那就没有super关键字
- 通过外部类名限定this对象 Outer5.this
这里是成员内部类
class Outer5{
public int num = 10;
class Inner5{
public int num = 20;
public void show(){
int num = 30;
System.out.println(num);//30
System.out.println(this.num);//20
System.out.println(Inner5.this.num);//20
System.out.println(new Outer5().num);//10
//Outer5.this 这里面的this指的就是Outer5
System.out.println(Outer5.this.num);//10
}
}
}
public class InnerClassDemo5 {
public static void main(String[] args) {
Outer5.Inner5 i = new Outer5().new Inner5();
i.show();
}
}
- 局部内部类:
- 可以直接访问外部类的成员
- 可以创建内部类对象,通过调用内部类的方法,来使用局部内部类的功能
class Outer6{
private int num = 100;
public void show(){
int num2 = 200;
class Inner6{
public void show1(){
System.out.println(num);
System.out.println(num2);//本来这地方应该报错的,但这里jdk在1.8之后自动添加了一个final,
// 看下面的代码可以很好的理解,num2被调用了两次,但实际上,用了一次之后,就消失了,JVM自动添加了一个final
/*
局部内部类访问局部变量必须要被final修饰
因为局部变量会随着方法的调用完毕而消失,这个时候,
局部对象并没有立马从堆内存中消失,还要使用那个变量。
为了让数据还能继续被使用,就用fianl修饰,
这样,在堆内存里面存储的其实是一个常量值
*/
}
}
System.out.println(num2);
Inner6 inner6 = new Inner6();
inner6.show1();
}
}
public class InnerClassDemo6 {
public static void main(String[] args) {
Outer6 outer6 = new Outer6();
outer6.show();
}
}
//200
//100
//200
我们查看了Outer6.class的字节码文件
发现JVM自动给外部类的成员加上了final关键字,让它可以多次被使用
匿名内部类
- 就是内部类的简化写法
- 前提:存在一个类或者接口
这里的类可以是具体类,也可以是抽象类 - 格式:new 类名或者接口名(){重写方法;}
- 本质是:是一个继承了这个类或者实现了这个接口的子类的匿名对象
匿名内部类的简单使用和一些改进 代码举例:
interface Inter{
public abstract void show();
public abstract void show2();
}
class Outer7{
public void fun() {
// new Inter() {
// public void show() {
// System.out.println("show()方法");
// }
// public void show2() {
// System.out.println("这是show2()方法");
// }
// }.show2();
//
// new Inter(){
// public void show(){
// System.out.println("这是show()方法");
// }
// public void show2(){
// System.out.println("这是show2()方法");
// }
// }.show();
//问题,如果我这个接口有很多方法,还需要使用匿名内部类的形式就很麻烦
//怎么改进
Inter inter = new Inter(){
public void show() {
System.out.println("这是show方法");
}
public void show2() {
System.out.println("这是show2方法");
}
};
inter.show();
inter.show2();
}
}
public class InnerClassDemo7 {
public static void main(String[] args) {
Outer7 outer7 = new Outer7();
outer7.fun();
}
}
//这是show方法
//这是show2方法
- 匿名内部类在开发中的使用
interface Person{
public abstract void studey();
}
class PersonDemo{
//接口作为参数的时候,需要的是实现该接口类的对象
public void fun(Person p){
p.studey();
}
}
class Student implements Person{
@Override
public void studey() {
System.out.println("学生学习");
}
}
public class InnerClassDemo8 {
public static void main(String[] args) {
Person p = new Student();
PersonDemo personDemo = new PersonDemo();
personDemo.fun(p);//学生学习
System.out.println("*********使用匿名内部类进行改进********");
personDemo.fun(
new Person() {
@Override
public void studey() {
System.out.println("这是匿名内部类的使用");
}
}
);
}
}
一个小练习来巩固匿名内部类的使用
按照要求,补齐代码
interface Inter{ void show(); }
class Outer{ //补齐代码 }
class OuterDemo(
public static void main(String[] args){
Outer.method().show();
}
}
要求在控制台输出"HelloWorld"
//通过:Outer.method().show()
//可以看出来 应该method是一个静态方法,因为静态方法直接.show()就使用了show方法
//又因为show方法是在Inter1中的,而Inter1是一个接口,所以method方法的返回值应该是Inter1接口类型
interface Inter1 { void show(); }
class In implements Inter1{
public void show(){
System.out.println("HelloWorld");
}
}
class Outer1{
public static Inter1 method(){
// 这是没有学习匿名对象的时候可以只有用
// In in = new In();
// in.show();
// return in;
// 学了匿名对象之后
return new Inter1() {
@Override
public void show() {
System.out.println("HelloWorld");
}
};
}
}
public class InnerClassDemo9 {
public static void main(String[] args) {
Outer1.method().show();
}
}
感谢阅读,我是啊帅和和,一位大数据专业即将大四学生,祝你快乐。