内部类在Android中有着大量的运用

内部类

内部类提供了更好的封装;内部类可以直接访问外部类的私有数据;匿名内部类适合那些只需要使用一次的类。非静态内部类不能拥有静态成员。内部类比外部类可以多使用三个修饰符:private、protected、static

将一个类定义在另一个类的里面,对里面那个类就称为内部类(内置类,嵌套类)

访问特点:

  • 内部类可以直接访问外部类中的成员,包括私有成员
  • 而外部类要访问内部类中的成员必须要建立内部类的对象

内部类的位置

内部类定义在成员位置上

  • 可以被private static成员修饰符修饰
  • 被static修饰的内部类只能访问外部类中的静态成员

内部类定义在局部位置上

  • 也可以直接访问外部类中的成员
  • 同时可以访问所在局部中的局部变量,但必须是被final修饰

非静态内部类

  • 成员内部类是类的成员而局部内部类和匿名内部类则不是
  • 使用ClassName.this.Xxx来调用外部类的重名变量
  • 内部类可以访问外部类的private变量,反之则不行。如果外部类要访问内部类的成员话,则必须显式创建非静态内部类对象来调用访问其实例成员
  • 不允许在非静态内部内定义静态成员

    外部类名.内部类名 变量名 = 外部类对象.内部类对象;

    Outer.Inner in = new Outer().new Inner();
class Outer {

	private int x = 3;

	class Inner {
int x = 4;
void function() {
int x = 5;
System.out.println("outer x: " + Outer.this.x);
}
}
}

静态内部类

  • 用static修饰的内部类,属于类本身
  • 可以包含静态成员也可以包含非静态成员
  • 静态内部类不能访问外部类的实例成员只能访问外部类的类成员。即使是静态内部类的实例方法也不能够访问外部类的实例成员
  • 外部类访问内部类的类成员可以使用类名调用,而实例成员可以通过实例调用
  • 当内部类中定义了静态成员,该内部类必须是static的

    new Outer.Inner().function();
class Outer {

	private static  int x = 3;

    static class Inner {//静态内部类
static void function(){
System.out.println("innner :"+x);
}
}
}

内部类的使用

  • 接口内定义的内部类都为public static修饰的
  • 内部类的使用:
    1. 在外部类中使用内部类
    2. 在外部类中以外使用非静态内部类
      • 此时内部类不可使用private修饰
      • OuterClass.InnerClass varName
      • OuterInstance.new InnerConstructor()
      class Out{
      class In{
      public In (String s){···}
      }
      }
      ···
      Out.In in = new Out().new In("test");
      //等价于
      Out.in in;
      Out out = new Out();
      in = out.new In("test");
      ···
      • 非静态内部类的构造器必须使用外部对象来调用。
      public class SubClass extends Out.In{
      //显示定义SubClass的构造器
      public SubClass ( Out out ){
      //通过传入的Out对象显式调用In的构造器
      out.super("hello");
      }
      }
    3. 在外部类以外使用静态内部类
      • new OuterClass.InnerConstructor()
      class StaticOut{
      static class StaticIn{
      public StaticIn(){···}
      }
      }
      ···
      StaticOut.StaticIn in = new StaticOut.StaticIn();
      //等价于
      StaticOut.StaticIn in;
      in = new StaticOut.StaticIn();

局部内部类

  • 若一个类存在于方法体中,则这个类称之为局部内部类,仅在该方法内有效。局部内部类不能在外部类的方法以外的地方使用,因此不能够使用static修饰
class Outer {

	int x = 3;

	void method(final int a) {
final int y = 4;
class Inner {
void function() {
System.out.println(y);
}
}
new Inner().function();
}
} class Test { public static void main(String[] args) {
Outer out = new Outer();
out.method(7); //当此语句执行完毕,释放内存
out.method(8);
}
}

匿名内部类

就是内部类的简化写法

前提:

  • 内部类可以继承或实现一个外部类或者接口

格式为:

  • new 外部类名或者接口名(){覆盖类或者接口中的代码,(也可以自定义内)}

简单理解:

  • 就是建立一个建立一个带内容的外部类或者接口的子类匿名对象
  1. 匿名内部类其实就是内部类的简写格式
  2. 定义匿名内部类的前提:内部类必须是继承一个类或者实现接口
  3. 匿名内部类的格式:new 父类或者接口(){定义子类的内容}
  4. 其实匿名内部类就是一个匿名子类对象。可以理解为带内容的对象
  5. 匿名内部类中定义的方法最好不要超过3个
abstract class AbsDemo {
abstract void show();
} class Outer {
int x = 3;
public void function() {
new AbsDemo() {
int num = 9;
void show() {
System.out.println("num = " + num);
}
void abc() {
System.out.println("增加的方法");
}
}.show();
}
} class Test {
public static void main(String[] args) {
new Outer().function();
}
}

匿名内部类的应用

interface Inter {
void method();
} class Test
{
//补足代码。通过匿名内部类。
/*
static class Inner implements Inter {
public void method() {
System.out.println("method run");
}
}
*/ static Inter function() {
return new Inter() {
public void method() {
System.out.println("method run");
}
};
}
} class InnerClassTest {
public static void main(String[] args) { //Test.function():Test类中有一个静态的方法function
//.method():function这个方法运算后的结果是一个对象。而且是一个Inter类型的对象
//因为只有是Inter类型的对象,才可以调用method方法
Test.function().method();
show(new Inter(){
public void method() {
System.out.println("method show run");
}
});
} public static void show(Inter in) {
in.method();
}
}

没有父类及接口如何使用匿名内部类

class InnerTest {
public static void main(String[] args) {
new Object() {
public void function() {
//方法主体
}
}.function();
}
}

Java8改进的匿名内部类

  • 匿名内部类适合只使用一次的类,其定义格式为:
new 实现接口() | 父类构造器(实参列表){
//匿名内部类的类体部分
}
  • 匿名内部类不能是抽象类,因为在创建匿名内部类的同时会创建对象
  • 匿名内部类不能定义构造器。由于匿名内部类没有类名,但却可以使用初始化块
  • 最常用的创建匿名内部类的方式是需要创建某个接口类型对象
interface Product{
public double getPrice();
public String getName();
}
public class AnonymousTest{
public void test ( Person p ){
System.out.println( "" + p.getName() + p.getPrice());
}
public static void main(String[] args){
AnonymousTest ta = new AnonymousTest();
ta.test(new Product(){
public double getPrice(){
return 123.4;
}
public String getName(){
return "书本";
}
});
}
}
class AnonymousProduct implements Product{
public double getPrice(){
return 123.4;
}
public String getName(){
return "书本";
}
}
ta.test ( new AnonymousProduct());
  • 在Java8以前,Java要求被局部内部类、匿名内部类访问的局部变量必须使用final修饰,从Java8开始这个限制被取消了:如果局部变量被匿名内部类访问,那么该局部变量相当于自动使用了final修饰

最新文章

  1. Hadoop学习笔记: 安装配置Hive
  2. VS2010+C#+AutoCAD2008时断点调试功能无效的处理方法
  3. LaTeX字体相关
  4. load and initialize
  5. Qt之QParallelAnimationGroup
  6. Java的Reference感觉很象C++的指针,但是区别是本质的
  7. start mysqld on Mac server
  8. Thinkphp 文本编辑器
  9. hdu 1241
  10. Qt中事件处理的方法(三种处理方法,四种覆盖event函数,notify函数,event过滤,事件处理器。然后继续传递给父窗口。可观察QWidget::event的源码,它是虚拟保护函数,可改写)
  11. c#反射(2)
  12. Android调试adb devices找不到设备【转】
  13. asp.net动态解析用户控件(UserControl)
  14. Hibernate之关联关系映射(一对多和多对一映射,多对多映射)
  15. springboot 初识
  16. 算法笔记_198:历届试题 打印十字图(Java)
  17. java中拼写xml
  18. kibana 与 grafana
  19. python开发_tkinter_窗口控件_自己制作的Python IDEL_博主推荐
  20. JS比较两个数组是否相等 是否拥有相同元素

热门文章

  1. Codeforces Round #590 (Div. 3)【D题:维护26棵树状数组【好题】】
  2. PHP mysqli_error() 函数
  3. 牛客小白月赛11 Rinne Loves Xor
  4. [Luogu] 1600
  5. 【概率论】3-8:随机变量函数(Functions of a Random Variable)
  6. 泰乐事(Telos)白皮书中文版 <一> 泰乐事项目(未完成)
  7. Spark(二)CentOS7.5之Spark2.3.1HA安装
  8. centos6中安装VMware Tools
  9. HDU 2859 Phalanx ——(DP)
  10. 修复grub rescue问题