内部类
定义:一个定义在类内部的类。之所以用内部类是因为使用内部类最吸引人的原因是:每个内部类都能独立地继承一个(接口的)实现,所以无论外围类是否已经继承了某个(接口的)实现,对于内部类都没有影响。可以这样说,接口只是解决了部分问题,而内部类使得多重继承的解决方案变得更加完整。
内部类:内部类可以有多个实例,每个实例都有自己的状态信息,并且与其他外部对象的信息相互独立。在单个外部类中,可以让多个内部类以不同的方式实现同一个接口,或者继承同一个类。创建内部类对象的时刻并不依赖于外围类对象的创建。内部类并没有令人迷惑的“is-a”关系,他就是一个独立的实体。内部类提供了更好的封装,除了该外围类,其他类都不能访问。内部类与外部类建立一种关系,可以访问外部类包括私有的属性。引用内部类首先创建内部类对象要用外部类对象来创建,OuterClass.InnerClass innerClass = outerClass.new InnerClass();内部类与外部类是编译时的概念,编译之后就是两个不同的class文件,内部类分为成员内部类,局部内部类、匿名内部类、静态内部类。
成员内部类::1)成员内部类中不能存在任何static的变量和方法;2)成员内部类是依附于外围类的,所以只有先创建了外围类才能够创建内部类。
- public class Outer {
- private String str;
- public void outerDisplay(){
- System.out.println("outer");
- }
- public class InnerClass{
- public void innerDisplay(){
- str = "ch";
- System.out.println(str);
- outerDisplay();
- }
- }
- public InnerClass getInnerClass(){
- return new InnerClass();
- }
- public static void main(String[] args) {
- Outer outer = new Outer();
- Outer.InnerClass inner = outer.getInnerClass();
- inner.innerDisplay();
- }
- }
局部内部类 :嵌套在方法和作用域内,用来解决复杂问题不创建公共的,就所谓的局部内部类,局部内部类和成员内部类一样被编译,只是作用域发生了改变,只能在该方法和属性内使用。
匿名内部类:Swing编程中,我们经常使用这种方式来绑定事件,
- button2.addActionListener(
- new ActionListener(){
- public void actionPerformed(ActionEvent e) {
- System.out.println("你按了按钮二");
- }
- });
使用匿名内部类我们必须要继承一个父类或者实现一个接口,当然也仅能只继承一个父类或者实现一个接口。同时它也是没有class关键字,这是因为匿名内部类是直接使用new来生成一个对象的引用。当然这个引用是隐式的。匿名内部类的使用它是存在一个缺陷的,就是它仅能被使用一次。创建匿名内部类时它会立即创建一个该类的实例,该类的定义会立即消失,所以匿名内部类是不能够被重复使用,匿名内部类为局部内部类,所以局部内部类的所有限制同样对匿名内部类生效。:匿名内部类不能是抽象的,它必须要实现继承的类或者实现的接口的所有抽象方法。
当所在的方法的形参需要被内部类里面使用时,该形参必须为final。内部类并不是直接调用方法传递的参数,而是利用自身的构造器对传入的参数进行备份,自己内部方法调用的实际上时自己的属性而不是外部方法传递进来的参数。内部类中我对属性的改变并不会影响到外部的形参,所以为了保持参数的一致性,就规定使用final来避免形参的不改变。匿名内部类没有构造器,使用构造代码块达到创造一个构造器的效果。
静态内部类:非静态内部类在编译完成之后会隐含地保存着一个引用,该引用是指向创建它的外部类,但是静态内部类却没有。没有这个引用就意味着:它的创建是不需要依赖于外部类的。2)它不能使用任何外围类的非static成员变量和方法。
- public class Outer {
- private String sex;
- public static String name = "che";
- static class InnerClass1{
- /* 在静态内部类中可以存在静态成员 */
- public static String _name1 = "che_static";
- public void display(){
- /*
- * 静态内部类只能访问外围类的静态成员变量和方法
- * 不能访问外围类的非静态成员变量和方法
- */
- System.out.println("OutClass name :" + name);
- }
- }
- class InnerClass2{
- /* 非静态内部类中不能存在静态成员 */
- public String _name2 = "che_inner";
- /* 非静态内部类中可以调用外围类的任何成员,不管是静态的还是非静态的 */
- public void display(){
- System.out.println("OuterClass name:" + name);
- }
- }
- public void display(){
- /* 外围类访问静态内部类:内部类. */
- System.out.println(InnerClass1._name1);
- /* 静态内部类 可以直接创建实例不需要依赖于外围类 */
- new InnerClass1().display();
- /* 非静态内部的创建需要依赖于外围类 */
- Outer.InnerClass2 inner2 = new Outer().new InnerClass2();
- /* 方位非静态内部类的成员需要使用非静态内部类的实例 */
- System.out.println(inner2._name2);
- inner2.display();
- }
- public static void main(String[] args) {
- Outer outer = new Outer();
- outer.display();
- }
- }
多重继承的实现
一个类可以同时从多个类继承行为和属性,java只支持单继承,那么实现多重继承的方式有接口和内部类。
接口实现:接口和抽象类的时候了解到子类只能继承一个父类,也就是说只能存在单一继承,但是却可以实现多个接口,接口是没有任何具体实现的,也就是说,没有任何与接口相关的存储。
- interface CanFight {
- void fight();
- }
- interface Swim {
- void swim();
- }
- interface Fly {
- void fly();
- }
- public class Action {
- public void fight(){
- }
- }
- public class Hero extends Action implements Fight,Fly,Swim{
- public void fly() {
- }
- public void swim() {
- }
- /**
- * 对于fight()方法,继承父类的,所以不需要显示声明
- */
- }
内部类实现多继承:
如果父类为抽象类或者具体类,那么我就仅能通过内部类来实现多重继承了。
- class Father {
- public int str(){
- return 2;
- }
- }
- class Mother {
- public int can(){
- return 2;
- }
- }
- class Son {
- class Father_1 extends Father{
- public int str(){
- return super.str() + 1;
- }
- }
- class Mother_1 extends Mother{
- public int can(){
- return super.can() - 2;
- }
- }
- public int get(){
- return new Father_1().str();
- }
- public int getcan(){
- return new Mother_1().can();
- }
- }
- public class Outer {
- public static void main(String[] args) {
- Son son = new Son();
- System.out.println( son.get());
- System.out.println( son.getcan());
- }
- }