内部类的定义
在Java的类中可以定义一个内部类
就是在"A类"中定义一个"B类"
类B是类A的内部类
类A是类B的外部类
内部类的成员是可以访问外部类的成员,私有也可以访问
//外部类
class Outer{
public int num = 10 ;
private int num2 =100 ;
//class Outer的内部类
class Inner{
//成员方法
public void show(){
System.out.println(num);
System.out.println(num2);
}
}
//外部类的成员方法
public void method(){
//show() ;
Inner inner = new Inner() ;
inner.show();
}
}
//测试类
public class OuterDemo {
public static void main(String[] args) {
//创建外部类对象
Outer outer = new Outer() ;
outer.method();
}
}
成员内部类:
在一个类的成员位置中定义的类
需求:测试类中直接访问成员内部类的成员方法:
访问的方式:
外部类名.内部类名 对象名 = 外部类对象.内部类对象;
前提条件:这个成员内部类---是一个非静态的成员内部类!
//外部类
class Outer3{
//成员变量
private int num = 100 ;
private static int num2 = 20 ;
//定义成员内部类
class Inner3{
//成员方法
public void show(){
System.out.println(num);
System.out.println(num2);
}
}
}
//测试类
public class OuterDemo3 {
public static void main(String[] args) {
// 外部类名.内部类名 对象名 = 外部类对象.内部类对象;
Outer3.Inner3 oi = new Outer3().new Inner3() ;
oi.show() ;
}
}
内部类的访问:
成员内部类可以被private修饰---保证数据的安全性:让外界不能new 来访问!
成员内部类也可以被static修饰:
它里面的成员访问外部类的成员特点:此时外部类的成员必须都是静态的
外界类中要访问静态的成员内部类的成员方法:
需要将静态的成员内部类---->看成是外部类的静态成员
外部类名.内部类名 对象名 = new 外部类名.内部类名() ;
非静态的成员内部类中,不能存在静态的成员---"冲突了"
public class Test1 {//外部类
private int sum = 10;
public static int sum1 = 20;
static class inner2{//静态的内部类
public void show(){
System.out.println(sum1);
//System.out.println(sum);静态成员无法访问非静态外部类的非静态变量
}
public static void show2(){//静态的成员方法
System.out.println(sum1);
}
}
}
class Testt{
public static void main(String[] args) {
//外部类名.内部类名 对象名 = 外部类对象.内部类对象;
// Test1.inner2 tt = new Test1.inner2(); 内部类是静态的所以访问不了
//外部类名.内部类名 对象名 = new 外部类名.内部类名() ;
Test1.inner2 tt = new Test1.inner2();
tt.show();
tt.show2();
}
}
局部内部类:在外部类的成员方法中定义的类,(非静态的)
局部内部类:在外部类的成员方法中定义的类,(非静态的)
直接可以访问外部类的包括私有
局部内部类访问局部变量的时候:
此时局部变量已经是常量了:被final修饰
jdk7以前:如果局部变量不显示的添加final关键字,编译报错!
jdk8版本,对当前局部内部类访问局部变量---此时变量在内存中已经优化为final了,不需要显示添加这个关键字!
为什么局部变量:是一个常量呢?
当外部类对象调用外部类的成员方法时候,num2随着method的方法调用而存在
随着method调用完毕,应该消失掉了;但是局部内部类的成员方法还在使用这个num2,所以
JVM进行了优化,JDK8以后 这个变量自动回加入final定义,所以这个必须是一个常量,那么内部类才能使用它!
外部类跟内部类没有继承关系,不要将内部类的外部类看作父类
//定义一个外部类
class Outer5{
private int num = 20 ;
public void method(){
//局部变量
int num2 = 50 ;// 常量 --->jdk8以后 :局部内部类访问这个局部变量,可以不书写final,隐藏的!
//局部内部类
class Inner5{
public void show(){
System.out.println(num);//Outer5.this.num:外部类的this限定
System.out.println(num2); //常驻内存--"常量池中"
}
}
Inner5 inner5 = new Inner5() ;
inner5.show();
}
}
public class OuterDemo5 {
public static void main(String[] args) {
//访问Inner5中的show
//创建外部类对象.调用method
Outer5 outer5 = new Outer5() ;
outer5.method();
}
}
匿名内部类
//什么是匿名内部类:
// 匿名内部类经常就是在局部位置使用!
// 格式"
new 类名/接口名(){
重写抽象方法{
....
}
};
//匿名内部类的本质是什么: 继承了该抽象类或实现了该接口的子类对象
//定义一个接口
interface Inter{
//有多个抽象方法:
void show() ;
void show2() ;
//定义一个类
class Demo{
//定义一个方法
public void method(){
Inter i = new Inter(){
@Override
public void show() {
System.out.println("show Inter...");
}
@Override
public void show2() {
System.out.println("show Inter2...");
}
} ;
i.show() ;
i.show2() ;
}
}
public class NoNameClassDemo {
public static void main(String[] args) {
//创建Demo类对象
Demo d = new Demo() ;
d.method();
}
}
匿名内部类在开发中的使用
方法的形式参数是类(具体类/抽象类),接口
//抽象的人类
abstract class Person{
public abstract void work() ;
}
//定义PersonDemo类
class PersonDemo{
public void method(Person p){//抽象类,需要抽象类的子类对象
p.work();
}
}
//定义一个子类
class Worker extends Person{
@Override
public void work() {
System.out.println("工人日日夜夜的coding...");
}
}
//测试类
public class PersonTest {
public static void main(String[] args) {
//需求:访问PersonDemo类中的method方法
PersonDemo pd = new PersonDemo() ;
//创建Person类对象---通过子类实例化
Person p = new Worker();
pd.method(p);
System.out.println("-----------------------");
//方式2:抽象类的匿名内部类
//需求:访问PersonDemo类中的method方法
PersonDemo pd2 = new PersonDemo() ;
pd2.method(new Person(){
@Override
public void work() {
System.out.println("工人日日夜夜的coding...");
}
});
}
}
方法的形式参数是接口类型,需要接口的子实现类对象!
也可以使用的接口匿名内部类!
interface Love{
public abstract void love() ;
}
class LoveDemo{
public void function(Love love){
love.love();
}
}
//定义接口的子实现类
class LoveImpl implements Love{
@Override
public void love() {
System.out.println("love Java!!!");
}
}
//测试类中
public class Test2 {
public static void main(String[] args) {
//要访问LoveDemo类中的function方法
//匿名内部类的使用
LoveDemo ld = new LoveDemo() ;
ld.function(new Love(){
@Override
public void love() {
System.out.println("love javaee...");
}
});
System.out.println("-----------------------------");
//要访问LoveDemo类中的function方法
LoveDemo ld2 = new LoveDemo() ;
Love love = new LoveImpl() ;//接口多态
ld2.function(love);
}
}
方法的返回值:引用类型 :抽象类/接口
如果是抽象类,那么返回该抽象类的子类对象
abstract class Person{
public abstract void study() ;
}
class StudentDemo{
public Person method(){
//不定义具体的子类,使用抽象类的匿名内部类
return new Person(){
@Override
public void study() {
System.out.println("good good Study,Day Day Up...");
}
};
}
}
//定义一个子类
class Student extends Person{
@Override
public void study() {
System.out.println("good good Study,Day Day Up...");
}
}
//测试类
public class Test1 {
public static void main(String[] args) {
//访问StudentDemo类中的method方法
StudentDemo sd = new StudentDemo() ;
Person person = sd.method(); //匿名内部类的本质:继承了该抽象类的子类对象
person.study();
}
}
方法的返回值:引用类型 :接口
interface Love{
void love() ;
}
class LoveDemo{
public Love function(){
//匿名内部类---接口的匿名内部类
return new Love(){
@Override
public void love() {
System.out.println("love JavaEE");
}
} ;
//方式2
/* Love love = new LoveImpl() ;//子实现类定义了
return love ;*/
}
}
class LoveImpl implements Love{
@Override
public void love() {
System.out.println("love Java");
}
}
//测试类
public class Test2 {
public static void main(String[] args) {
LoveDemo ld = new LoveDemo() ;
Love love = ld.function();
love.love();
}
}