java基础之内部类

内部类是一个定义在另一个类中的类。那为什么要使用内部类呢?其主要原因有以下三点

1.内部类方法可以访问该类定义所在的作用域中的数据,包括私有数据

2.内部类可以对统一包中的其他数据隐藏起来,增强面向对象的封装性

3.当想定义一个回调函数且不想编写大量代码时,使用匿名内部类比较便捷

借助于内部类可以实现类似于多继承的作用

 public class Person { 
     //人在出生的时候选择性别 
     private String[] sex = {"男性","女性"};  
     class Xiaoming{ 	
         private String xiaoming_sex; 	
         private String  showSex() { 
             // TODO Auto-generated method stub 	
             xiaoming_sex = sex[1]; 	
             return xiaoming_sex; 	
         }
     } 
     //在外部类当中定义一个方法展示小明的性别 
     private void show_XiaoMing_sex() { 	
         // TODO Auto-generated method stub
         Xiaoming xiaoming = new Xiaoming();
         System.out.println(xiaoming.showSex()); 
     } 	
     public static void main(String[] args) { 	
         Person person = new Person(); 	person.show_XiaoMing_sex(); 
     }
 }

为了能够运行程序,内部类的对象总有一个隐式引用,他指向了创建他的外部类对象.

2.内部类的特殊与法规规则

①:内部类当中所有的静态域必须是final。原因很简单。我们希望一个静态域只能有一个实例,不过对于每个外部对象,都会有一个单独的内部类实例。如果这个域不是final,他可能就不是唯一的。

②:内部类不能有static方法。java语言规范没有对这个限制做出任何解释。假设如果有静态方法,那么也只能访问外围类的静态域和方法。显然,Java设计者认为相对于这种复杂性而言,它带来的好处有些得不偿失。

内部类的几种表现形式

一、成员式内部类

定义:成员式内部类如同外部类的一个普通方法

成员式内部类有以下特性:

1.持有父类引用,故可以访问父类任何访问权限的变量、方法

2.若有static修饰,那就是类级,否则为对象级。类级通过外部类直接访问,对象级需要先生成外部的对象后才能访问

3.非静态内部类中不能声明static成员

上边的代码就是成员式内部类

如何访问成员式内部类:

外部类名.内部类名 变量名 = new 外部类名().new 内部类名();

Person.Xiaoming xiaoming = new Person().new Xiaoming();

二、局部内部类

1.什么是局部内部类

定义:局部内部类就是定义在代码块、方法体内、作用域({})内的类。

 public class Person {
     //人在出生的时候选择性别 
     private static String[] sex = {"男性","女性"}; 
     public void print() { 	
         class People { 	
             private String name = "xiaoming"; 	
             public void print() { 		
                 System.out.println("hello world"); 	
             } 	
         } 	
         People people = new People();
         people.print();
     } 
 }

测试:

public class Test {
    public static void main(String[] args) {
        Person person = new Person(); 
        person.print(); 
    } 
}

局部内部类有以下特性:

1.不能使用public、private、protected、static等这些修饰符

2.局部内部类只能在当前方方法中使用,作用域范围仅限于当前方法中

3.局部内部类和实例内部类一样,不能拥有静态成员,但可以访问外部成员的所有变量

4.局部内部类访问的局部变量必须使用fianl修饰,在jdk8中自动隐士的加上了final,但是依然是常量,值不能被改变

为什么不推荐使用局部内部类?

如果当前方法不是main方法,那么当前方法调用完毕之后,当前方法的栈帧就会被销毁,方法内部的局部变量的空间也会被销毁。

三、匿名内部类

定义:匿名内部类是局部内部类的一种特殊形式,是一个没有名称的内部类。

注意:匿名内部类必须继承一个父类或者一个接口

1.匿名内部类的由来

首先新建一个抽象类

public abstract class Person { 
    void sleep() {} 
}

继承这个抽象类并实现它的方法

public class Student  extends Person{
    private void sleep() {
        // TODO Auto-generated method stub 
        System.out.println("学生在吃"); 
    }  
}

最后调用

public class Demo3 { 
    public static void main(String[] args) { 
        Person person = new Student(); 
        person.sleep(); 
    } 
}

可以看到我们在这里使用了多态的思想,将student类向上转型到person类当中,这里我们只是用了一次student类,把我们有没有什么办法跳过这个student类来实现person当中的方法呢?

我们进行相关的改动后:

public class Demo3 { 
    public static void main(String[] args) { 	
        new Person() { 	
            void sleep() { 		
                System.out.println("学生正在睡觉。。。。"); 	
            }; 	
        }.sleep(); 
    } 
}

可以看到继承了person类,并在()中实现了响应的抽象方法。

最后这是我们重用的匿名内部类的方式:

public class Person{ 
    public static void main(String[] args) { 
        new Thread() { 		
            @Override 	
            public void run() { 	
                for(int i=0;i<10;i++) {
                    //3.将要执行的代码,写在run方法中 
                    System.out.println("aaaaaaa"); 
                } 		
            } 	
        }.start();
    }
}

 

最常用的就是利用匿名内部类的方式来开辟一个新的线程.

lamda表达式

不需要传入参数

public class Person{ 
    public static void main(String[] args) { 
      new Thread(
                () ->{ System.out.println("Thread run()");// 省略接口名和方法名
            }).start();
    }
}

对于有参的,这里就是上一篇复习中的重写Comparator接口,对于sort()的第二个参数本来应该是Comparator接口的实现类的实例,这里直接用lamda表达式实现了这个接口。

public static void main(String[] args) {
    String[] abc={"abc","bc","cccc","daffff"};
    Arrays.sort(abc);
    System.out.println(Arrays.toString(abc));
    Arrays.sort(abc,(first, seconde) -> first.length()-seconde.length());
    System.out.println(Arrays.toString(abc));
}

四、静态内部类

定义:有时候,使用内部类只是为了把一个类隐藏在另一个类的内部,并不需要内部类引用外围类对象。为此,我们可以将内部类声明为static,以便取消产生的引用。

特点:

1.在创建外部类实例的时候不必创建外部类实例。

OuterClass.InnerClass in = new OuterClass.InnerClass();

2.静态内部类可以直接访问访问外部类的静态成员

3.在静态内部类可以定义静态和非静态的成员

4.外部类可以通过完整的类名直接访问静态内部类的静态成员。

public class OuterClass { 
    String name = "Outer.name"; 
    static String name2 = "Outer.name2"; 
    static class InnerClass{
        private void printNmae() { 	
            // TODO Auto-generated method stub 	
            System.out.println(name2); 	
            System.out.println(new OuterClass().name); 
        } 
    } 
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值