• 内部类


    内部类

    一个简单的Demo

    创建内部类时,首先需要有外部类对象

    下面的代码中使用两种方式来创建内部类

    public class TestSet {
    
    	public static void main(String[] args) {
    		// 第一种方式获取内部类
    		TestSet testSet = new TestSet();
    		TestSet.Test test1 = testSet.getTest();
    
    		// 第二种方式获取内部类
    		TestSet.Test test2 = new TestSet().new Test();
    	}
    
    	class Test {
    	}
    
    	public Test getTest() {
    		return new Test();
    	}
    }
    

    对象的传递

    所有的内部类自动拥有对其外围类所有成员的访问权

    在下面的例子中外部类有个属性outer且为私有类型,在内部类中直接对外部类的outer进行了赋值操作,通过两次打印输出,我们看到outer的值发生了变化。注意:内部类只是对外部类的方法和属性有访问权,但这些属性和方法只属于外部类。

    public class TestSet {
    	private int outer = 0;
    	public static void main(String[] args) {
    		TestSet testSet = new TestSet();
    		System.out.println(testSet.outer);
    
    		TestSet.Test test2 = testSet.new Test();
    		System.out.println(testSet.outer);
    	}
    
    	class Test {
    		public Test() {
    			outer = 10;
    		}
    	}
    }
    

    内部类的继承与覆盖

    子类可以继承父类的内部类(非private),但是内部类不存在覆盖的情况。因为内部类来自于不同的名字空间

    class Contents {
    	protected int i;
    	class Test {
    		{
    			System.out.println("Contents.Test");
    		}
    	}
    }
    
    public class TestSet extends Contents {
    	class Test {
    		{
    			System.out.println("TestSet.Test");
    		}
    	}
    	public static void main(String[] args) {
    		Contents contents = new TestSet();
    		Contents.Test test = contents.new Test();
    	}
    }
    

    上面的代码输出结果为Contents.Test

    静态内部类

    静态内部类也叫嵌套类,如果不需要内部类对象与外部类对象之间有联系,则可以将内部类声明为static。静态内部类对象不会隐式的持有外部类对象引用,所以静态内部不能直接使用外部类的非静态属性和方法。

    public class TestSet {
    	private int i = 0;
    	static class Test {
    		public Test() {
    			// 无法访问TestSet的i成员
    			// i = 10;
    		}
    	}
    }
    

    匿名内部类

    匿名内部类是没有名字的内部类,先看一个demo:

    interface Contents {
    
    }
    
    public class TestSet {
    	public Contents contents() {
    		return new Contents() {
    			private int i = 0;
    		};
    	}
    
    }
    

    在上面的例子中,我们创建一个实现Contents接口的匿名类对象,通过new表达式返回的引用自动向上转型为Contents,由于匿名类没有名字,所以不能为其添加构造器。

    class Contents {
    	public Contents() {
    	}
    	public Contents(int x) {
    
    	}
    }
    
    public class TestSet {
    	public Contents getContents(final int x) {
    		return new Contents(x) {
    			private int i = x;
    		};
    	}
    }
    

    上面的代码中我们在创建匿名内部类对象时为其传入了参数x,这是因为基类Contents有个有参构造器。并且我们发现getContents方法的参数必须被final修饰,这是因为我们在匿名类内部访问了该参数(i = x)

    如果我们想要在构造器中添加一些逻辑可以使用下面的方式,大括号中的内容会直接被添加到匿名类的构造函数中去

    abstract class Contents {
    	protected int i;
    	public Contents() {
    
    	}
    	public Contents(int x) {
    
    	}
    }
    
    public class TestSet {
    	public Contents contents(final int x) {
    		return new Contents(x) {
    			{
    				if (x > 0)
    					i = 10;
    				else
    					i = x;
    			}
    		};
    	}
    }
    

    小结

    内部类丰富了多重继承的问题,可以通过内部类来达到继承多个基类的效果。如果在继承上有方法冲突,则可以用内部类解决

    闭包

    闭包是一个可以调用的对象,它不仅记录了自己的信息,而且还记录了一些来自于创建它的作用域的信息。内部类就是面向对象的闭包。它扩大了我们对域的访问范围。

  • 相关阅读:
    Maven No sources to compile
    [ERROR] Failed to execute goal org.apache.maven.plugins:maven-assembly-plugin:2.4:single (make-assembly) on project hive-udf: Error reading assemblies: No assembly descriptors found. -> [Help 1]
    在使用maven时出现Invalid packaging for parent pom.xml, must be _pom_ but is _xxx类问题的处理
    blogs
    resouces
    Natural Language Processing with Python 1.1
    Fundamentals of Python: Preface
    移动互联网
    时间都去哪儿了
    凝思磐石安全操作系统官方版 下载
  • 原文地址:https://www.cnblogs.com/xidongyu/p/6828452.html
Copyright © 2020-2023  润新知