回顾static关键字:
①static可以修饰属性、方法、代码块、内部类;
②static不可以修饰构造器
内部类
代码理解:
package com.atguigu.java3;
/*
* 类的内部成员之内部类
* 1,Java中允许将一个类A声明在另一个类B中,则类A即为内部类,类B称为外部类
* 2,内部类的分类:成员内部类、局部内部类(方法内、代码块内、构造器内)
* 3,成员内部类:一方面,作为外部类的成员;
* ①调用外部类的结构
* ②内部类可以被static修饰(普通类不能使用static修饰)
* ③作为外部类的成员可以被四种不同权限修饰符修饰。(普通类只能被public、缺省修饰)
* 另一方面,作为一个类:
* ①其中可定义属性、方法、构造器等
* ②可以被final修饰,表示此类不能被继承
* ③可以被abstract修饰,表示此类不可被实例化)
*
* 4,关注如下三个问题:
* ①如何实例化成员内部类的对象
* ②如何在成员内部类中调用外部类的结构
*/
public class InnerClassTest {
public static void main(String[] args) {
//①如何实例化成员内部类的对象
//创建Dog实例(静态的成员内部类)
Person.Dog dog=new Person.Dog(); //注意格式
dog.show(); //卡拉是条狗
//创建Bird实例(非静态的成员内部类)------>注意此处为非静态
Person p= new Person();
Person.Bird bir=p.new Bird(); // 有了对象之后通过对象调用内部结构
bir.Sing(); //我是一只小小鸟 干饭
System.out.println("*********");
bir.display("黄鹂");
}
}
class Person{ //外部类
String name="小明"; //外部类name属性
int age;
public void eat(){
System.out.println("干饭");
}
//静态成员内部类
static class Dog{ //内部类可以被static修饰(普通类不能使用static修饰)
String name;
int age;
public void show(){
System.out.println("卡拉是条狗");
// eat(); //注意:此处注释打开会报错,eat()为非静态在内存中加载时间晚,而此类为静态要先加载,所以不能调用
}
}
//非静态成员内部类
class Bird{
String name="杜娟"; //内部类name属性
public Bird(){
}
public void Sing(){
System.out.println("我是一只小小鸟");
//调用外部类的结构(此处调用的是非静态属性)
eat(); //内部类和外部类没有重名,可以省略,完整为:Person.this.eat();表示Person类对象的eat()方法
}
//有属性重名时怎么调用:
public void display(String name){ //形参name
System.out.println(name); //调用形参
System.out.println(this.name); //调用内部类属性 ,this调用的是display方法所在类的name
System.out.println(Person.this.name); //调用外部类属性,Person里的name
}
}
public void method(){
//局部内部类(方法内)
class AA{
}
}
//局部内部类(代码块内)
{
class BB{
}
}
//局部内部类(构造器内)
public Person(){
class CC{
}
}
}
开发中局部内部类的使用:
package com.atguigu.java3;
// 开发中局部内部类的使用
public class InnerClassTest1 {
//此即为局部内部类
public void method(){
//局部内部类
class AA{
}
}
//开发中较为常见的应用场景
public Comparable getComparable(){ //此方法返回一个实现了Comparable接口的实现类的对象。Comparable是一个接口
//创建一个实现了Comparable接口的类--->局部内部类
//方式一:标准方式
// class MyComparable implements Comparable{
// @Override //重写接口中的抽象类方法
// public int compareTo(Object o) {
// return 0;
// }
// }
// return new MyComparable();
//方式二:匿名方式:创建一个实现Comparable接口的匿名实现类的匿名对象
return new Comparable(){
@Override
public int compareTo(Object o) {
return 0;
}
};
}
}
局部内部类使用的一个注意点:
package com.atguigu.java3;
/*规定:
* 在局部内部类(如:show)的方法中,如果调用局部内部类所声明的方法(method方法)中的局部变量的话,
* 要求此局部变量(num)声明为final的。
* jdk7之前版本要求显式声明;jdk8之后版本可以省略final声明
*
*/
public class InnerClass3 {
public void method(){
int num=10; //完整为:final int num=10;
//局部内部类
class AA{
public void show(){
// num=20; 此处注释打开会报错,原因是num实际上是final修饰的
System.out.println(num);
}
}
}
}