java 内部类_Little_Cloudy的博客-程序员宅基地

技术标签: java  匿名内部类 内部类  

一、基本概念
内部类:将一个类定义在另一个类里面,那么里面这个类就称为内部类(内置类,嵌套类)
根据内部类定义在外部类中的位置可分为:
 (1)成员内部类:内部类所处位置与外部类的成员变量、成员方法并列,相当于外部类的一个成员(类)
 (2)局部内部类:内部类所处位置在外部类的某个成员方法体内,相当于成员方法的一个局部量(类)
作用:
  (1)在某种程度上实现多重继承,若B类嵌套定义在A类之内,是A类的一个内部类,则在A派生C类时,C类可以继承A类的成员,也因B是A类的成员类,故也被C类继承。
  (2)对外而言,内部类可以实现信息隐藏
  (3)可以避免修改接口而实现同一个类中两种同名方法的调用
二、成员内部类
示例1:
interface Overtime{
       void prepareLesson();
       void checkHomework();
}
class Teacher{
      void work(){
          System.out.println("传道受业,教书育人!");
      }
     private class ExtraWork implements Overtime{
            public void prepareLesson() {
                 System.out.println("抓紧时间,认真备课!");
             }
            public void checkHomework() {
                   System.out.println("抓紧时间,改好作业!");
            }      
     }
     ExtraWork prepare(){
                  return new ExtraWork();
     }
}  
public class Test {
    public static void main(String[] args) {
        Teacher t=new Teacher();
        Overtime w=t.prepare();
        w.prepareLesson();
        w.checkHomework();
  }
}
   我们在Teacher类中嵌套定义了一个private访问权限的ExtraWork类(内部类),实现了Overtime接口的两个方法。在后面的main方法里,直接用Overtime w进行操作、调用接口方法实现相应功能。在Test类的main方法中,我们甚至连这个内部类的名字都没有看见!----实现了信息隐藏,也即封装性。
   当然,在外部类作用范围之外调用内部类的方法,需要在外部类中定义一个返回值为内部类类型的成员方法。上例中的prepare()方法就是这么做的。由于内部类ExtraWork的访问权限定义为private,所以在外部类之外是不可以直接访问该类的。

示例2:
class Outer{
     private String str="Java学习笔记";  //定义外部类的私有属性
     public class Inner {    //声明内部类
   public void getStr(){    //定义内部类的方法
     System.out.println(str);
   }
     }
     public void getInfo(){            //从外部类调用内部类的方法
        Inter in= new Inter();        //创建内部类实例
         in.getStr();
     }
}
public class InnerClassDemo01 {
    public static void main(String[] args) {
          Outer out=new Outer(); //创建外部类的实例
  out.getInfo(); //调用外部类的方法
 // Outer.Inner oin=new Outer().new Inner();//通过匿名外部示例创建内部类实例
            Outer.Inner oin=out.new Inner();//通过外部类示例out来创建内部类的实例  
oin.getStr();//调用内部类的方法
      }
}
   当内部类不是private访问权限时,可以在外部类之外创建内部类实例,通过内部类实例访问其方法。
   语法格式: 外部类名.内部类名   内部类引用对象=外部类实例.new 内部类();
总结:成员内部类可以访问外部类的成员,内部类方法需要创建内部类实例对象去调用。
示例3:外部类成员变量、内部类成员变量和内部类方法局部变量同名是的区分
class OutClass {
    private int age = 12;     
    class InClass {
        private int age = 13;
        public void print() {
            int age = 14;
            System.out.println("局部变量:" + age);
            System.out.println("内部类变量:" + this.age);
            System.out.println("外部类变量:" + Out.this.age);
        }
    }
}


三、静态内部类
   当成员内部类前有关键词static时,该成员内部类就是一个静态(成员)内部类。   
示例4:
 class OutClass {
    private static int age = 12;     
    static class InClass {
        public void print() {
            System.out.println(age);
        }
    }

public class Demo {
    public static void main(String[] args) {
        Out.In in = new Out.In();
        in.print();
    }
}
 总结:静态成员内部类只能访问外部类的静态成员。
      在外部类之外创建静态内部类实例语法格式:外部类名.内部类名  内部类引用对象=new 外部类名.内部类();


四、方法内部类(局部内部类)
   内部类所处位置在外部类的某个成员方法体内,相当于成员方法的一个局部量(类)
示例5:
   定义一个学生课程成绩管理类,为每个学生统计成绩使用:
   基本属性:课程名,课程考试成绩,课程平时成绩,加权值。
   基本方法:设置课程名,设置成绩,设置加权值,输出课程信息(课程名称和总成绩)
class  CourseGrade{
  String courseName;
  double examGrade;
  double usualGrade;
  double ratio;
  void setName(String name){courseName=name;}
  void setGrade(double egrade,double ugrade){examGrade=egrade;uaualGrade=ugrade;} 
  void setRatio(double ratio){this.ratio=ratio;}
  void print(){
      class CalGrade{
          double cal(){
             return examGrade*ratio+usualGrade*(1-ratio);
          }
      }
      System.out.println("课程名称:"+courseName);
      System.out.println("课程总成绩:"+new CalGrade().cal());
  }
}
总结:方法内部类可以访问外部类的成员。
      但却只能访问方法的final局部变量包含形参,因为当方法被调用运行完毕之后,局部变量就已消亡了。
      而内部类对象可能还存在(直到没有被引用时才会消亡)此时就会出现内部类要访问一个不存在的局部变量。


 示例6:
class Out{
    private int age=12;
    public void Print(final int x){
          class In{
                public void inPrint() {
                           System.out.println(x);  //可以访问外部类成员变量
                          System.out.println(age); //只能访问方法的final局部变量,包括形参
                }
           }
           new In().inPrint();
   }
}


五、匿名内部类
1、匿名内部类其实就是内部类的简写格式
2、定义匿名内部类的前提:
         内部类必须继承一个类或者实现接口
3、匿名内部类的格式
new 父类或者接口(){  定义子类的内容  }
4、其实匿名内部类就是一个匿名子类对象,可以理解为带内容的对象。
5、匿名内部类中定义的方法尽量不超过2个,当有多个方法时,可以通过匿名内部类中的构造代码块进行调用。
   通过匿名内部类的匿名子类对象只能调用一个方法。
示例7:
interface CalGrade{
   double cal();
}
class  CourseGrade{
  //.......示例5代码省略部分
  void print(){      
      System.out.println("课程名称:"+courseName);
      System.out.println("课程总成绩:"+new CalGrade(){
 public double cal(){
             return examGrade*ratio+usualGrade*(1-ratio);
          }
      }.cal());
  }
}
     

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/nc_yhy/article/details/78491999

智能推荐

【C++】C++11 新特性(auto,decltype,nullptr,快速遍历,【Lambda表达式详解】)_c++11 数组快速遍历_萌宅鹿同学的博客-程序员宅基地

C++11 重要新特性autodecltypenullptr快速遍历与数组初始化Lambda 表达式Lambda 应用外部变量捕获mutableauto可以从初始化表达式中推断出变量的类型,大大简化编程工作属于编译器特性,不影响最终的机器码质量,不影响运行效率#include <iostream>#include <typeinfo>using namesp...

i5 4590+ASUS B85 Pro Gamer+RX570黑苹果10.14.3的EFI分享_阿华Wickham的博客-程序员宅基地

目录硬件需求什么东西工作什么东西没测试什么东西不工作安装前须知安装后操作其他EFI细节下载地址硬件需求i5 4590ASUS B85 Pro Gamer蓝宝石RX574超白金什么东西工作CPU变频,H264解码。声卡网卡显卡。睡眠及唤醒。所有USB端口,包括前置,包括3.0及2.0。后置音频输入及输出,前置音频输入及输出。独立显卡DP输出。什么东西没测试主板自带的显...

proxmox7.0中动态调整centos stream磁盘大小_lwprain的博客-程序员宅基地

具体环境是这样:在proxmox中新建了一个虚拟机,磁盘大小为40G。正常安装系统后,创建了挂在在/的磁盘,容量为35G,swap分区为4G。现在由于空间不足,需要增加虚拟机的磁盘大小。查了很多资料,做不到我想要的,后来通过摸索发现如下可做到。1、虚拟机关进,在虚拟机硬件中,增加磁盘容量40G。2、打开虚拟机后,执行fdisk -l,会发现sda2仍然为35G。3、执行cfdisk /dev/sda,执行resize操作,将sda2增加为75G。4、执行 pvresize /dev/sda2

Ubuntu 16.04虚拟机调整窗口大小自适应Windows 7_所谓伊人,在水一方的博客-程序员宅基地

Windows 7上Ubuntu 16.04虚拟机安装成功后,默认的虚拟机窗口比较小,需要适当调整,才能把虚拟机的屏幕放大, 适合使用,以下介绍调整方法。安装VMware Tools启动虚拟机,在虚拟机管理界面上,主屏幕菜单”虚拟机”中点击”安装vmware tools(T)”,开始安装vmware tools. 虚拟机管理中心会提醒用户默认的操作步骤.这可以无视.稍等几秒,虚

北邮计算机网络实验-用开源代码实现一个SIP客户端_sip 源代码_Track0_0的博客-程序员宅基地

文章目录一、背景知识1.1 VOIP1.2 SIP协议1.3 实验要求二、实验准备2.1实验环境2.2 PJSIP开源项目下载2.3 Visual Studio安装2.4 QT下载安装(实现视频通话)2.5 下载SDL(实现视频通话)2.6下载FFmpeg(实现视频通话)三、 实现在呼叫中心的注册3.1 项目编译3.2 呼叫中心注册3.2.1 呼叫IVP3.2.2 注册组号3.2.3 登录四、实现视频电话4.1 编译pjsip的底层支持4.1.1 文件准备4.1.2 建立链接4.2 编译pjsip的图形界面

python软件可以申请著作权吗_什么样的软件可以申请软件著作权?_得宝进步课堂的博客-程序员宅基地

谢邀,因为不知道你描述的作品实际情况,这里就从定义上给予回答吧。首先什么是计算机软件?计算机软件是指计算机程序及其有关文档。计算机程序是指能实现一定功能的代码化指令序列,或者符号化语句序列。文档指用来描述程序的内容、组成、设计、功能规格、开发情况、测试结果及使用方法的文字资料和图表,如程序设计说明书、流程图、用户手册等。这样你作为行业产业人员的话其实已经很好理解了 此外给说一下软件著作权登记的一些...

随便推点

整型int和字节数组byte相互转换_全速前行的博客-程序员宅基地

<br />public class Test { public static void main(String args[] ) { int i = 212123; byte[] b = toByteArray(i, 4); //整型到字节, System.out.println( "212123 bin: " + Integer.toBinaryString(212123));//212123的二进制表示 Syst

OpenAtom XuperChain开发者夏季论坛落幕,多位行业大咖共话开源区块链前景_百度超级链xuper的博客-程序员宅基地

6月25日,开放原子开源基金会和百度超级链在上海共同举办OpenAtom XuperChain开发者夏季论坛,开放原子开源基金会可信账本工作组执行秘书刘涛、百度区块链技术负责人荆博和北京邮...

ajax post传不过去,Ajax POST方式发送请求服务器接收不到数据问题解决办法_weixin_39963744的博客-程序员宅基地

直接看源码代码如下function setViewPoint() {var msg =""; //用于接收返回数据//实例化Ajaxvar leeAjax = leeInitAjax();var webRoot = window.location;webRoot = webRoot.toString();var domain = webRoot.substring(7);var endD = do...

layer-list 实现EditText线性背景_layer 背景顶部有线_luohaowang320的博客-程序员宅基地

先是 红色背景,然后在上面盖一个白色的,离底部5dp,所以就留出5dp高度的红色了效果如下:但是 看着有点蛋疼,待输入光标盖在了背景线上了。 在第一层加了

Android平台挖矿木马研究报告_FLy_鹏程万里的博客-程序员宅基地

360烽火实验室摘 要手机挖矿木马就是在用户不知情的情况下利用其手机的计算能力来为攻击者获取电子加密货币的应用程序。 电子加密货币是一种匿名性的虚拟货币,由于不受政府控制、相对匿名、难以追踪的特性,电子加密货币常被用来进行非法交易,也成为犯罪工具、或隐匿犯罪所得的工具。 2014年3月首个Android平台挖矿木马被曝光。 从2013年开始至2018年1月,360烽火实验室共捕获An...

推荐文章

热门文章

相关标签