内部类:
把类定义在其他类的内部,我们称之为内部类
内部类有哪些特点:
1、内部类可以访问外部类的成员,包括私有
2、外部类要想访问内部类的成员,必须要创建内部类的对象
package com.shujia.wyh.day13;
class Outer{
private int num = 10;
class Inner{
public void show(){
System.out.println(num);
}
}
public void fun(){
//创建内部类对象
Inner inner = new Inner();
inner.show();
}
}
public class InnerClassDemo1 {
public static void main(String[] args) {
Outer outer = new Outer();
outer.fun();
}
}
按照内部类在类中定义的位置不同,可以分为如下两种格式:
成员位置(成员内部类)
局部位置(局部内部类)
package com.shujia.wyh.day13;
class Outer2{
//定义在成员的位置上(成员内部类)
class Inner2{
}
public void fun(){
//定义在局部范围内(局部内部类)
class Inner3{
}
}
}
public class InnerClassDemo2 {
}
成员内部类:外部类名.成员内部类名 对象名 = new 外部类名().new 成员内部类名();
1、定义在类的成员位置上
2、内部类可以方法外部类的成员,包括私有的
package com.shujia.wyh.day13;
class Outer3{
private int num = 10;
class Inner{
public void show(){
System.out.println(num);
}
}
}
public class InnerClassDemo3 {
public static void main(String[] args) {
//正确创建成员内部类对象的格式
//外部类名.成员内部类名 对象名 = new 外部类名().new 成员内部类名();
Outer3.Inner oi3 = new Outer3().new Inner();
oi3.show();
//相当于
// Outer3 outer3 = new Outer3();
// Outer3.Inner inner = outer3.new Inner();
// inner.show();
}
}
成员内部类常见的修饰符:
static: 内部类如果是被static修饰的时候,只能访问外部类中静态成员
package com.shujia.wyh.day13;
class Outer4 {
private static int num = 200;
static class Inner4 {
public static void fun() {
System.out.println(num);
}
}
}
public class InnerClassDemo4 {
public static void main(String[] args) {
//当内部类是被静态所修饰的时候,出现了另外一种创建内部类的方式
//外部类名.内部类名 对象名 = new 外部类名.内部类名();
// Outer4.Inner4 oi4 = new Outer4.Inner4();
// oi4.fun();
//直接通过类名直接调用
Outer4.Inner4.fun();
}
}
private: 其他类不能直接创建内部类的对象,要想使用被private修饰内部类成员,必须在本类中间接的创建对象调用
package com.shujia.wyh.day13;
class Outer4 {
private int num = 200;
private class Inner4{
public void fun(){
System.out.println(num);
}
}
//被private修饰内部类成员其他类不能直接创建内部类的对象,必须在本类中间接的创建对象调用
public void show() {
Inner4 inner4 = new Inner4();
inner4.fun();
}
}
public class InnerClassDemo4 {
public static void main(String[] args) {
//不能直接创建内部类的对象
// Outer4.Inner4 oi4 = new Outer4().new Inner4();
// oi4.fun();
Outer4 outer4 = new Outer4();
outer4.show();
}
局部内部类:
1、定义在方法中的类
2、局部内部类可以直接方法外部类中所有成员
3、要想使用局部内部类中的方法,在定义局部内部类的成员方法中,创建局部内部类对象调用方法。
package com.shujia.wyh.day13;
class Outer6{
private int num = 10;
public void fun(){
int num2 = 20;
class Inner6{
int num3 = 300;
public void show(){
num3 = 30;
//在局部内部类中引用的本地的变量必须是最终变量或者实际上的最终变量
//存在局部内部类的方法中定义的局部变量自动加上了final关键字
// num2 = 22;
num = 44;
System.out.println(num);//44
System.out.println(num2);//20
System.out.println(num3);//30
}
}
//在定义局部内部类的成员方法中,创建局部内部类对象调用方法
Inner6 inner6 = new Inner6();
inner6.show();
}
}
public class InnerClassDemo6 {
public static void main(String[] args) {
Outer6 outer6 = new Outer6();
outer6.fun();
}
}
匿名内部类
语句定义格式:
new 类名(可以是抽象类也可以具体的类)/接口(){
要重写的方法;
};
匿名内部类存在的前提:
要存在一个类或者是一个接口,这个类可以是具体的类也可以是抽象的类
本质: 是一个继承了类或者实现了接口的子类匿名对象
interface A{
b();
c();
}
class B implements A{
b(){...};
c(){...};
}
A a = new B();
a.b();
a.c();
通过匿名内部类改进:
A a = new A(){
b(){...}
c(){...}
};
其实new A(){b(){...}c(){...}};相当于new B();是创建子类的对象,可以用父类的引用接收(多态)
package com.shujia.wyh.day13;
interface Inter{
public abstract void show();
public abstract void show2();
}
//不使用匿名内部类需要一个类实现接口再创建对象
//class B implements Inter{
//
// @Override
// public void show() {
//
// }
//
// @Override
// public void show2() {
//
// }
//}
//Inter i = new B()
class Outer7{
public void fun(){
//使用匿名内部类的形式创建对象调用show方法
new Inter(){
@Override
public void show() {
System.out.println("这是show方法");
}
@Override
public void show2() {
System.out.println("这是show2方法");
}
}.show();
//使用匿名内部类的形式创建对象调用show2方法
new Inter(){
@Override
public void show() {
System.out.println("这是show方法");
}
@Override
public void show2() {
System.out.println("这是show2方法");
}
}.show2();
System.out.println("======================================");
//利用接口多态的形式给匿名内部类起名字
Inter inter = new Inter(){
@Override
public void show() {
System.out.println("这是show方法");
}
@Override
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();
}
}
1、使用匿名内部类进行方法传参
package com.shujia.wyh.day13;
interface Person{
public abstract void study();
}
class PersonDemo{
Person person; //引用数据类型
PersonDemo(){}
PersonDemo(Person person){ // Person person = new Student();
this.person = person;
}
public void fun(Person person){
person.study();
}
}
public class InnerClassDemo8 {
public static void main(String[] args) {
//使用匿名内部类的形式创建对象
Person person = new Person() {
@Override
public void study() {
System.out.println("好好学习,天天向上");
}
};
person.study();
//使用匿名内部类进行方法传参
PersonDemo personDemo = new PersonDemo(new Person() {
@Override
public void study() {
System.out.println("这是匿名内部类使用带参构造方法");
}
});//PersonDemo personDemo = new PersonDemo(person)
new PersonDemo(new Person() {
@Override
public void study() {
System.out.println("这是匿名内部类使用带参构造方法");
}
}).fun(new Person() {
@Override
public void study() {
System.out.println("好好学习天天向上2");
}
});//new PersonDemo(person).fun(person)
new PersonDemo(new Person() {
@Override
public void study() {
System.out.println("这是匿名内部类使用带参构造方法");
}
}).person.study();//new PersonDemo(person).person.study()
}
}
2、使用匿名内部类进行方法返回返回值
interface Inter { void show(); }
class Outer { //补齐代码 }
class OuterDemo {
public static void main(String[] args) {
Outer.method().show();
}
}
要求在控制台输出”HelloWorld
1、根据main方法调用的代码推出第一个结论:method()是静态的,可以直接通过类名访问/调用
2、根据main方法中调用完method()方法之后,还能继续调用方法,我们判定method()是有返回值的
而再观察后发现,show()方法恰好是Inter2接口中的方法,所以返回值类型是接口Inter2类型
根据调用method()方法的参数是空,所以判定method()方法没有参数
package com.shujia.wyh.day13;
interface Inter2{
void show();
}
class Outer8{
public static Inter2 method(){
return new Inter2() {
@Override
public void show() {
System.out.println("HelloWorld");
}
};
}
}
public class InnerClassDemo9 {
public static void main(String[] args) {
Outer8.method().show();
}
}