类的成员
属性
静态属性
非静态属性
方法
静态方法
非静态方法
构造器
代码块
静态代码块
非静态代码块
内部类: 将一个类写到了另一个类的内部成员内部类 参考 成员变量 常见于源码
静态成员内部类 静态成员变量 常见于源码
局部内部类 局部变量
匿名内部类 匿名对象
成员内部类(一)
成员内部类:
1.位置
class 外部类名{
class 内部类名{}
}
2.外部类只能使用 public default 修饰
成员内部类 可以被四种权限修饰符修饰
3.在内部类中可以直接使用外部类的所有资源4.外部类中可以使用内部类资源(需要在外部方法中创建内部类的对象,用对象.的方式可以调用内部类的资源)
5.可以采用内部类实现多继承的效果
让内部类 外部类都去继承另一个类6.内部类中不能声明静态的资源 但是可以有静态的常量;
(因为静态资源是随着类的加载而加载,要优先加载,此时类是非静态,而此时就变成了先加载静态资源在加载类矛盾了,因此成员内部类中不能声明静态资源)
7.内部类会产生独立的字节码文件 命名方式
外部类名$内部类名.class
Outer$Inner.class
public class Outer {
String name = "Outer";
class Inner{
int age = 18;
public void innerMethod1(){
System.out.println("this is innerMethod1");
}
public void innerMethod(){
System.out.println(name);
outerMethod();
}
}
public void outerMethod(){
System.out.println("this is outerMethod");
}
public void outerMethod1(){
//创建内部类
Inner inner = new Inner();
System.out.println("this is outerMethod1");
}
}
class C{
public void c(){};
}
class D{
public void d(){};
}
public class Test {
public static void main(String[] args) {
Outer outer = new Outer();
outer.outerMethod1();
Outer.Inner inner = outer.new Inner();
inner.innerMethod();
System.out.println(inner.age);
Outer.Inner inner1 = new Outer().new Inner();
System.out.println(inner1.age);
}
}
获取内部类的两种方式
Outer.Inner inner = outer.new Inner();
inner.innerMethod();
System.out.println(inner.age);Outer.Inner inner1 = new Outer().new Inner();
System.out.println(inner1.age);
new是一个工具,需要用外部对象拿着new 使用new然后才能创建内部类对象。
成员内部类同名属性:(就近原则 现在内部类的方法中找,然后再到内部类的成员变量找,最后再到外部类的成员变量找)
比如name Outer.this.属性名 内部类中 this.属性名 属性名
静态成员内部类(二)
静态成员内部类:
1.位置
class 外部类名{
static class 内部类名{
}
}
2.静态内部类可以有静态的资源(静态资源是随着类的加载而加载的,类是静态的,因此可以有静态资源)
3.静态内部类 不能【直接】使用 外部类的非静态资源
可以创建外部类对象使用 外部类的非静态资源
4.可以实现多继承的效果
5.外部类使用静态内部类资源
静态资源 内部类名.资源名
非静态资源 内部类对象名.资源名
6.静态内部类有独立的字节码文件
命名方式 外部类名$内部类名.class
Outer$Inner.class
7.使用内部类资源
7.1内部类静态资源
外部类名.内部类名.资源名;
7.2内部类非静态资源
外部类名.内部类名 对象名 = new 外部类名.内部类名();(我的理解 静态资源都需要用类名.的方式调用,静态内部类作为外部类的静态资源,因此在实例化对象的时候,可以用new Outer.Inner()的方式)
Outer.Inner inner = new Outer.Inner();
public class Outer {
static String name = "Outer";
int age = 20;
static int num = 30;
static class Inner {
static int num = 20;
public static void showNum(){
int num =10;
System.out.println(num);
System.out.println(Inner.num);
System.out.println(Outer.num);
}
public void innerMethod1() {
Outer outer = new Outer();
System.out.println("outer.age = " + outer.age);
System.out.println(name);
}
public static void innerStaticMethod1() {
System.out.println("this is static innerStaticMethod1 ");
}
public void innerMethod2() {
System.out.println("this is innerMethod2() ");
}
}
public void outerMethod(){
//内部类静态资源
Inner.innerStaticMethod1();
System.out.println("Inner.num = " + Inner.num);
Inner inner = new Inner();
//内部类非静态资源
inner.innerMethod2();
}
}
public class Test {
public static void main(String[] args) {
Outer outer = new Outer();
outer.outerMethod();
System.out.println("----- 静态 ------");
System.out.println("Outer.name = " + Outer.name);
System.out.println("Outer.Inner.num = " + Outer.Inner.num);
Outer.Inner.innerStaticMethod1();
System.out.println("----- 非静态 ------");
// Outer.Inner inner = new Outer().new Inner();
Outer.Inner inner = new Outer.Inner();
inner.innerMethod2();
}
}
局部内部类(三)
局部内部类:
位置:方法内
1.局部内部类使用外部类资源
1.1 如果局部内部类在普通方法中 可以直接使用外部类所有资源
1.2 如果局部内部类在静态普通方法中 可以直接使用外部类静态资源
2.局部内部类 只能被 权限修饰符 default 修饰 不能使用static可以使用 final abstract
3.局部内部类中不能有静态的资源 但是可以有静态常量
4.局部内部类也会产生独立的字节码文件 命名方式
外部类名$序号内部类名.class
Outer$1A.class
Outer$2A.class 序号从1开始5. 如果局部内部类中 使用了方法中的局部变量 那么 此变量 会被final修饰
jdk8之前 手动添加final
jdk8(含)之后 自动添加final
public class Outer {
static String name = "Outer";
int num = 10;
public static void main(String[] args) {
}
public void method(){
int n = 30;
n = 25;
System.out.println(n);
/* A a = new A();
a.innerMethod();*/
//现有类才能被初始化,因此顺序不能变
class A{
final static int m = 10;
//可以使用外部类资源
public void innerMethod(){
System.out.println(name);
System.out.println(num);
// System.out.println(n);
}
}
A a = new A();
a.innerMethod();
}
//局部内部类想要使用什么样的资源,不是由
//局部内部类本身决定的而是由它所在的方法
//决定的,局部内部类的地位相对来说比较低。
public static void staticMethod(){
class A{
final static int m = 10;
public void innerMethod(){
System.out.println(name);
// System.out.println(num);
}
}
}
}
练习一:
public class Test {
public static void main(String[] args) {
A a = getValue(); //返回一个B类对象相当于 A a = new B() 相当于多态
int num = a.getNum();//此时会调用重写后的方法
System.out.println("num = " + num);
}
public static A getValue(){
int m = 10;
class B implements A{
@Override
public int getNum() {
return m;
}
}
B b = new B();
return b;
}
}
interface A{
int getNum();
}
内名内部类
匿名内部类:
没有名字的内部类
1.创建匿名内部类的形式
1.1 new 类名(构造器){};
1.2 new 接口名(){};
2.创建匿名内部类 会有两个作用
2.1创建了该类/接口的匿名子类
2.2创建了该/接口匿名子类对象3.匿名内部类会生成独立的字节码文件
命名方式 外部类名$序号.class
Test$1.class4.匿名内部类是特殊的局部内部类 在方法中
(因此如果内部类使用了该方法的局部变量,则该局部变量默认会被final修饰)
public class Test3 {
public static void main(String[] args) {
SuperMan superMan = new SuperMan();
flying(superMan);
}
public static void flying(FlyAble flyAble){ // FlyAble flyAble = new SuperMan()
flyAble.fly();
}
}
class SuperMan implements FlyAble{
@Override
public void fly() {
System.out.println("超人飞.....");
}
}