java基础==========多态、(成员、静态、局部、匿名)内部类

多态和内部类

虽然java这些知识点都是很基础的东西,但是等我到用的时候,总是模棱两可的回忆起大概,这就是我java基础不牢固的表现,每天坚持写一篇java基础,以此来打牢自己的基础。坚持~坚持,关于这篇自己的总结是看了下面的博客,加上自己的理解https://blog.csdn.net/m366917/article/details/52124604

在说内部类之前,我觉得先要了解一下什么是多态,因为对于后面匿名内部会比较好理解。多态通俗一点就是,子类可以持有父类的引用,父类也可以向下转型成子类,使用子类的方法,(Fu fu = new ZI(); 或者 Fu fu = new Fu(); ZI zi = (ZI)fu)

下面看一段代码
定义一个父类(A.java)

public class A {
    public int numA = 100;

    public void Ashow() {
        System.out.println("show A");
    }

    public static void Afunction() {
        System.out.println("function A");
    }
}

定义一个子类(B.java)

public class B extends A{
    public int numB =10;
    public int numA = 10;
    public void Ashow(){
        System.out.println("修改的Ashow");
    }
    public void Bshow() {
        System.out.println("show B");
    }

    public static void Bfunction() {
        System.out.println("function B");
    }

}

测试一下

public class C {
    public static void main(String[] args){
        //成员
        A a = new B();
        System.out.println(a.numA); //只能调动A的成员变量
        a.Ashow();                  //只能调用A中Ashow方法,但是请看运行结果
        a.Afunction();              //同上
    }
}
//这里注意一下输出结果:
    100
    修改的Ashow
    function A

结果说明了什么,
对于成员变量来说 :编译看左边,运行看左边,所以只能调用A的成员变量。
对于成员方法来说:编译看左边,运行看右边,也就是new B();B中有Ashow方法,相当于重写了A中的Ashow方法,这里其实调用了B中的Ashow方法。
之后a.Afunction,看B中没有Afunction方法,所以只能使用A中的成员方法。
所以多态的弊端不能使用子类特有的功能。
如果想使用子类的方法,看下面的代码

public class C {
    public static void main(String[] args){
        //成员
        A a = new B();
        System.out.println(a.numA);
        a.Ashow();
        a.Afunction();
        //向下转型
        B b = (B) a;
        b.Bshow();
        b.Bfunction();
    }
}
//输出结果:
    100
    修改的Ashow
    function A
    show B
    function B

============================多态就复习到这里==========================================
下面就来说说内部类

成员和局部内部类

看代码

定义一个成员和局部内部类都存才的类(AOuter.java)

public class AOuter {
   private int num = 100;
   //成员位置定义一个类,就是成员内部类
   class BInner{
       private int num = 200;
        public void Bshow(){
            System.out.println(num);
        }
   }
   public void method(){
       //在方法里定义类,就是局部位置--局部内部类
       class CInner{
           public void Cshow(){
               System.out.println("Cshow");
           }
       }
       //在方法类创建局部内部类对象,然后使用其功能
       CInner c = new CInner();
       c.Cshow();
   }
}

测试一下方法

public class Test {
   public static void main(String[] args){
       AOuter.BInner b = new AOuter().new BInner();
       b.Bshow();
       AOuter a= new AOuter();
       a.method();
   }
}
//输出的结果:
200
Cshow

从上面的代码结果可以总结出两点,一个是内部类可以直接访问外部类的成员变量,二是局部内部类要是用时,可以在方法体内定义对象,那个这个类的生命周期就跟方法一致了。
接下来修改一下method中的代码

 public void method(){
         int Cnum = 300;
       //在方法里定义类,就是局部位置--局部内部类
       class CInner{
           public void Cshow(){
               System.out.println("Cshow");
               System.out.println("Cnum"+Cnum);//访问局部变量
               System.out.println("num"+num); //访问外部类的变量
           }
       }
       //在方法类创建局部内部类对象,然后使用其功能
       CInner c = new CInner();
       c.Cshow();
   }

注意这里我们是可以访问到局部变量Cnum的值得,但是为什么局部内部类访问它所在方法的局部变量时,要求该局部变量必须声明为final,原因就是内部类对象的生命周期比局部变量的生命周期长
就会报错,(在jdk8.0能编译通过,那是因为它检测到局部内部类访问了 x,会默认给 x 的前面加上隐式的final,如果我在int Cnum = 300后面加一句Cnum = 10;编译器将会报错,因为final不允许 x 的值改变)

静态内部类

看代码
定义一个静态内部类(BOuter.java)

public class BOuter {
    private int num = 10;
    private static int num2=100;
    public static class CInner{
        public void show(){
//          System.out.println("show static"+num);
            System.out.println("show static"+num2);
        }
    }
}

测试一下

public class Test {
   public static void main(String[] args){
    new BOuter.CInner().show();
   }
}
结果:
show static100

匿名内部类

一般是定义一个接口,也可以定义一个抽象类
然后new 一个接口或者抽象类,并且实现其中的方法,这个new 出的接口或者抽象类可以想象成是一个没有名字的子类,继承了这个接口或抽象类,看代码

       //使用匿名内部类访问局部变量
       //定义一个接口或者抽象类
       public abstract class D {
           public abstract void Dshow();
          }
         //用匿名内部类的方法来实现
         new D(){
            @Override
            public void Dshow() {   
            }
         };

其实这个new D()可以想象成 new 匿名 extend/implements D(){实现方法}

关于这几个内部类的使用场景,有篇博客很好,https://blog.csdn.net/u011240877/article/details/78682097

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值