精华内容
下载资源
问答
  • java的内部类

    千次阅读 2020-06-15 17:40:53
    Java-为什么非静态内部类里面不能定义静态方法、静态成员变量、静态初始化块?:https://blog.csdn.net/hello123yy/article/details/81129903?utm_source=blogxgwz0 静态内部类:...

    参考博客:

    内部类测试类,如下:

    package com.ming.interview.inner;
    
    import com.ming.interview.inner.Outer.Inner;
    
    /**
     * @ClassName: Outer
     * @Description: TODO(外部类和内部类、静态内部类)
     * @author lenovo
     * @date 2020年6月15日
     *
     */
    
    /*
     * 总结:
     * 1.内部类不能有静态成员变量、静态方法、静态代码块等,通过查看jvm类加载的过程不难理解这个问题:
     * 在类加载的时候,静态属性和代码块会先加载,那么按照这个逻辑,非静态内部类里面的静态属性也要优先于这个内部类加载,但这个时候这个内部类都还没有初始化,这就出现矛盾了。
     * 2.【外部类属性、方法访问修饰符】和【内部类类、属性、方法访问修饰符】只针对外部类之外的其他类,在当前外部类和内部类不起作用【外部类和内部类看成一个整体,内部类属于外部类的一部分,相互没有访问限制的】
     * 3.静态类内部不可以访问外部类的实例成员,只能访问外部类的类成员
     */
    public class Outer {
    	private String name;
    	
    	/*
    	 * 外部类私有方法
    	 */
    	private static void get() {
    		System.out.println("外部类私有方法");
    	}
    	
    	/*
    	 * 外部类私有静态方法
    	 */
    	private static void getStatic() {
    		System.out.println("外部类私有静态方法");
    	}
    	
    	/*
    	 * 外部类调用内部类私有方法
    	 */
    	public void processInnerGet() {
    		new Inner().get();
    	}
    	
    	/*
    	 * 内部类
    	 */
    	class Inner {
    		/*
    		 * 内部类私有方法
    		 */
    		private void get() {
    			System.out.println("内部类私有方法" + name);
    		}
    		
    		/*
    		 * 内部类调用外部类私有方法
    		 */
    		private void processOuterGet() {
    			new Outer().get();
    		}
    		
    		/*
    		 * 内部类调用外部类私有静态方法
    		 */
    		private void processOuterGetStatic() {
    			Outer.getStatic();
    		}
    	}
    	
    	
    	/*
    	 * 外部类调用静态内部类静态方法
    	 */
    	public static void processInnerStaticGetStatic() {
    		InnerStatic.getStatic();
    	}
    	
    	/*
    	 * 外部类调用静态内部类非静态方法
    	 */
    	public static void processInnerStaticGet() {
    		new InnerStatic().get();
    	}
    	
    	/*
    	 * 静态内部类
    	 */
    	static class InnerStatic {
    		/*
    		 * 私有静态方法
    		 */
    		private static void getStatic() {
    			System.out.println("静态内部类私有静态方法");
    			
    			//静态类内部不可以访问外部类的实例成员,只能访问外部类的类成员
    			System.out.println("静态内部类私有静态方法" + name);
    		}
    		
    		/*
    		 * 静态方法
    		 */
    		private void get() {
    			System.out.println("静态内部类私有非静态方法");
    			
    			//静态类内部不可以访问外部类的实例成员,只能访问外部类的类成员
    			System.out.println("静态内部类私有静态方法" + name);
    		}
    		
    	}
    	
    	
    	/*
    	 * 私有内部类
    	 */
    	private class InnerProtecet {
    		
    	}
    }
    
    
    class Outer1 {
    	
    	public void test() {
    		Outer outer = new Outer();
    		//创建内部类对象方式一
    		Outer.Inner inner1 = outer.new Inner();
    		//创建内部类对象方式二
    		Outer.Inner inner2 = new Outer().new Inner();
    		
    		//创建私有内部类对象:其他类无法创建私有内部类对象
    		outer.new InnerProtecet();
    		
    		//内部类的私有方法get()只能在内部类或其对应的外部类中访问
    		inner1.get();
    		
    		//静态内部类的私有静态方法getStatic()只能在内部类或其对应的外部类中访问
    		Outer.InnerStatic.getStatic();
    	}
    	
    }
    
    
    展开全文
  • JAVA的内部类学习总结

    千次阅读 2015-02-15 23:45:39
    这几天看书,开始在前面看到了JAVA的内部类,开始以为往后看,可以看懂,结果看到了时间监听那里也没有看懂。 再说自己写JAVA代码有个毛病,可能是写C++和C语言写多了,就是喜欢把每一个类都单独的写在一个文件里面...

    这几天看书,开始在前面看到了JAVA的内部类,开始以为往后看,可以看懂,结果看到了时间监听那里也没有看懂。

    再说自己写JAVA代码有个毛病,可能是写C++和C语言写多了,就是喜欢把每一个类都单独的写在一个文件里面。

    根本就不存在嵌套或者是一个文件写有几个类的问题。

    接下俩给大家总结内部类的含义,以及使用。

    这里还分享几个不错的博客:


    http://www.cnblogs.com/nerxious/archive/2013/01/24/2875649.html

    http://android.blog.51cto.com/268543/384844/

    内部类的共性


    (1)、内部类仍然是一个独立的类,在编译之后内部类会被编译成独立的.class文件,但是前面冠以外部类的类名和$符号 。
    (2)、内部类不能用普通的方式访问。内部类是外部类的一个成员,因此内部类可以自由地访问外部类的成员变量,无论是否是private的 。
    (3)、内部类声明成静态的,就不能随便的访问外部类的成员变量了,此时内部类只能访问外部类的静态成员变量 。



    //======================================================================================//

    说到这里有一个问题,问什么要引入内部类?


    典型的情况是,内部类继承自某个类或实现某个接口,内部类的代码操作创建其的外围类的对象。所以你可以认为内部类提供了某种进入
    其外围类的窗口。使用内部类最吸引人的原因是:
    每个内部类都能独立地继承自一个(接口的)实现,所以无论外围类是否已经继承了某个(接口的)实现,对于内部类都没有影响。如果
    没有内部类提供的可以继承多个具体的或抽象的类的能力,一些设计与编程问题就很难解决。从这个角度看,内部类使得多重继承的解决
    方案变得完整。接口解决了部分问题,而内部类有效地实现了“多重继承”。


    //======================================================================================//


    内部类分为以下几种:

    1、成员内部类;

    2、方法内部类;

    3、匿名内部类;

    4、静态嵌套类;

    1、成员内部类
    例子

    class Outer {
    class Inner{}
    }
    编译上述代码会产生两个文件:Outer.class和Outer$Inner.class。

    2、方法内部类
    把类放在方法里
    class Outer {
    public void doSomething(){
    class Inner{
    public void seeOuter(){
    }
    }
    }
    }
    (1)、方法内部类只能在定义该内部类的方法内实例化,不可以在此方法外对其实例化。
    (2)、方法内部类对象不能使用该内部类所在方法的非final局部变量
    因为方法的局部变量位于栈上,只存在于该方法的生命期内。当一个方法结束,其栈结构被删除,局部变量成为历史。但是该方法结束之后,在方法内创建的内部类对象可能仍然存在于堆中!例如,如果对它的引用被传递到其他某些代码,并存储在一个成员变量内。正因为不能保证局部变量的存活期和方法内部类对象的一样长,所以内部类对象不能使用它们。
    下面是完整的例子:
    class Outer {
    public void doSomething(){
    final int a =10;
    class Inner{
    public void seeOuter(){
    System.out.println(a);
    }
    }
    Inner in = new Inner();
    in.seeOuter();
    }
    public static void main(String[] args) {
    Outer out = new Outer();
    out.doSomething();
    }
    }


    3、匿名内部类
    顾名思义,没有名字的内部类。表面上看起来它们似乎有名字,实际那不是它们的名字。
    当程序中使用匿名内部类时,在定义匿名内部类的地方往往直接创建该类的一个对象。匿名内部类的声明格式如下:
    new ParentName(){
    ...// 内部类的定义
    }[1] 
    匿名内部类就是没有名字的内部类。什么情况下需要使用匿名内部类?如果满足下面的一些条件,使用匿名内部类是比较合适的:
    ·只用到类的一个实例 。
    ·类在定义后马上用到。
    ·类非常小(SUN推荐是在4行代码以下)
    ·给类命名并不会导致你的代码更容易被理解。
    在使用匿名内部类时,要记住以下几个原则:
    ·匿名内部类不能有构造方法
    ·匿名内部类不能定义任何静态成员静态方法。
    ·匿名内部类不能是public,protected,private,static。
    ·只能创建匿名内部类的一个实例。
    ·一个匿名内部类一定是在new的后面,用其隐含实现一个接口或实现一个类。
    ·因匿名内部类为局部内部类,所以局部内部类的所有限制都对其生效。
    A、继承式的匿名内部类
    public class Car {
    public void drive(){
    System.out.println("Driving a car!");
    }
    public static void main(String[] args) {
    Car car = new Car(){
    public void drive() {
    System.out.println("Driving another car!");
    }
    };
    car.drive();
    }
    }
    结果输出了:Driving another car! Car引用变量不是引用Car对象,而是Car匿名子类的对象。
    B、接口式的匿名内部类。
    interface Vehicle {
    public void drive();
    }
    class Test{
    public static void main(String[] args) {
    Vehicle v = new Vehicle(){
    public void drive(){
    System.out.println("Driving a car!");
    }
    };
    v.drive();
    }
    }
    上面的代码很怪,好像是在实例化一个接口。事实并非如此,接口式的匿名内部类是实现了一个接口的匿名类。而且只能实现一个接口。
    C、参数式的匿名内部类。
    class Bar{
    void doStuff(Foo f){
    f.foo();
    }
    }
    interface Foo{
    void foo();
    }
    class Test{
    static void go(){
    Bar b = new Bar();
    b.doStuff(new Foo(){
    public void foo(){
    System.out.println("foofy");
    }
    });
    }
    }
    4、静态嵌套类
    静态内部类中可以定义静态或者非静态的成员。
    从技术上讲,静态嵌套类不属于内部类。因为内部类与外部类共享一种特殊关系,更确切地说是对实例的共享关系。而静态嵌套类则没有上述关系。它只是位置在另一个类的内部,因此也被称为顶级嵌套类。
    静态的含义是该内部类可以像其他静态成员一样,没有外部类对象时,也能够访问它。静态嵌套类仅能访问外部类的静态成员和方法。
    class Outer{
    static class Inner{}
    }
    class Test {
    public static void main(String[] args){
    Outer.Inner n = new Outer.Inner();
    }
    }
    在静态方法中定义的内部类也是StaticNested Class,这时候不能在类前面加static关键字,静态方法中的StaticNested Class与普通方法中的内部类的应用方式很相似,它除了可以直接访问外部类中的static的成员变量,还可以访问静态方法中的局部变量,但是,该局部变量前必须加final修饰符。

    展开全文
  • Java的内部类和匿名类 , 您了解过吗?

    千次阅读 多人点赞 2020-07-23 08:35:30
    内部类是指在一个外部类的内部再定义一个类,内部类作为外部类的一个成员,是依附于外部类存在的。 内部类可以是静态的,通常用 protected 或者 private 关键字修饰,外部类只能使用public或者系统默认权限。 如果...

    本文原创首发CSDN,本文链接 https://blog.csdn.net/qq_41464123/article/details/107480664 ,作者博客https://blog.csdn.net/qq_41464123 ,转载请带上本链接,谢谢配合。



    零、为什么要写内部类?

     

    之前在学习Android百度地图的时候,发现一个Activity中居然有两个嵌套的类(Class),成功引起了我的注意,于是最近在暑假系统了学习了Java中的四种内部类。

    最初在大二入门Java的时候,我就了解过Java的匿名类和内部类,那时候觉得这些都是理论性的东西,实际开发不一定能用到,于是就淡化了。直到最近,发现Java的内部类机制在实际开发中用处还是不小的,于是系统的学习了内部类,并写下了这篇总结。

     


    一 、类

     

    1.1 基础类

     

    类的概念、访问权限修饰符,我已经在《学习Java的你,真的会面向对象编程吗?》详细讲解了。

    类是什么?类是静态的模板,规定了 将该类实例化的对象 的共性。

    public class People {
    	
    	String userName;
    	int userAge;
    	
    	void say() {
    		System.out.println("The people " + this.userName + " is "+ this.userAge + " years old!");
    	}
    }

    看,这就是一个 People 类,他有成员变量 userNameuserAge,还有成员方法say()

     

    1.2 封装类

     

    如果结合上Java的封装原则,那么,就需要为成员变量、成员方法加上访问权限修饰符,代码就变成了这个样子:

    public class People {
    	
    	private String userName;
    	private int userAge;
    	
    	public void say() {
    		System.out.println("The people " + this.userName + " is "+ this.userAge + " years old!");
    	}
    
    	public String getUserName() {
    		return userName;
    	}
    	public void setUserName(String userName) {
    		this.userName = userName;
    	}
    	public int getUserAge() {
    		return userAge;
    	}
    	public void setUserAge(int userAge) {
    		this.userAge = userAge;
    	}
    }

    从程序功能上来说,前后两段代码的功能是一致的,但是从Java语言开发规范角度来讲,每一个实体类都必须满足封装原则,简单来讲,实体类的成员变量必须为私有类型,并且提供 set 和 get 方法让外部获取、修改变量。

    可以说,上面这段程序才是真正意义上的Java实体类Bean。

     


    二、内部类

     

    我的理解:内部类就是类中类,依附于普通类中,可以间接实现Java类的多继承。

    内部类是指在一个外部类的内部再定义一个类,内部类作为外部类的一个成员,是依附于外部类存在的。

    内部类可以是静态的,通常用 protected 或者 private 关键字修饰,外部类只能使用public或者系统默认权限。

    如果你对Java的访问权限不熟悉,可以看一下我这篇文章《一文搞懂Java的 构造方法 和 访问权限》

    内部类主要有四种,分别是成员内部类、方法内部类、静态内部类、匿名内部类(图片来源于网络,侵删)

     


    2.1 成员内部类

     

    成员内部类,顾名思义就是内部类作为成员存在于类中,和成员变量、成员方法同级。

    比如下面这个 People 类,包含了一个内部类 Book,该类和成员变量 userName 、userAge 同级。

    Book内部类,也可以拥有自己的成员变量、成员方法,以及自身的构造方法

    public class People {
    
    	class Book{
    		String bookName;
    		
    		Book(String bookName){
    			this.bookName = bookName;
    		}
    		
    		void open() {
    			System.out.println("The " + this.bookName + " was opened!");
    		}
    	}
    }

    我们如果要实例化这个成员内部类,就必须采用

    外部类.内部类 内部类对象 = new 外部类().new 内部类();

     实际代码如下:

    public class Main {
    
    	public static void main(String[] args) {
    		People.Book book = new People().new Book("Java程序设计"); 
    		book.open();
    	}
    }

     运行效果如下,也就是调用了内部类 Book 的 open() 方法,输出这样一句话。

     


    2.2 静态内部类

     

    在讲解静态内部类之前,先讲解一下静态,也就是static关键字

    static是静态的意思。在Java语言中,static关键字修饰的成员是可以被所有对象共享的。

    如果某个类加了static关键字,则直接可以使用类名直接访问。

    将2.1小节的People类中的 Book子类,加上一个 static关键字 修饰

    static class Book{
    	String bookName;
    	
    	Book(String bookName){
    		this.bookName = bookName;
    	}
    	
    	void open() {
    		System.out.println("The " + this.bookName + " was opened!");
    	}
    }

    那么外部就直接可以使用类名进行实例化操作,就像一个普通实例类一样,如下面代码所示:

    import cn.zwz.People.Book;
    
    public class Main {
    
    	public static void main(String[] args) {
    		Book book = new Book("Java程序设计"); 
    		book.open();
    	}
    }

     我们可以得到和 2.1小节所讲的一致的效果。


    本文原创首发CSDN,本文链接 https://blog.csdn.net/qq_41464123/article/details/107480664 ,作者博客https://blog.csdn.net/qq_41464123 ,转载请带上本链接,谢谢配合。


    2.3方法内部类

     

    方法内部类是指在Java方法中定义的类。

    我们在原有的 People 类中,定义一个say()方法,在该方法中定义一个 Issue 内部类。

    在 Issue 内部类中,定义一个方法 speakIsser(),内容是输出话题的名称。

    public class People {
    	
    	public void say(String issue) {
    		class Issue {
    			public void speakIsser() {
    				System.out.println("My issues is " + issue);
    			}
    		}
    		new Issue().speakIsser();
    	}
    }

    接着编写测试方法,实例化一个 People 对象,并调用 people 的 say() 方法

    public class Main {
    
    	public static void main(String[] args) {
    		People people = new People();
    		people.say("Hello ZWZ!");
    	}
    }

    运行结果显示,people 的 say() 方法,调用了 Issue内部类中的 speakIsser()方法,输出了这句话。

     


    2.4匿名内部类

     

    我们对第三小节的程序稍加修改

    1. 定义一个Issue接口,或者普通类。

    2. 在 People 类的 say()方法中,new 出来一个 Issue 对象,实现 speakIsser() 抽象方法的具体实现。

    3. 在Issue对象的后面调用speakIsser()方法。

    代码如下所示:

    interface Issue{
    	public void speakIsser();
    }
    public class People {
    	
    	public void say(String issue) {
    		new Issue() {
    			public void speakIsser() {
    				System.out.println("My issues is " + issue);
    			}
    		}.speakIsser();
    	}
    }

    测试方法程序,同第三小节的方法内部类,不做修改

    public class Main {
    
    	public static void main(String[] args) {
    		People people = new People();
    		people.say("Hello ZWZ!");
    	}
    }
    

    运行结果如下图所示,即效果同第三小节的方法内部类。

     

    匿名内部类是一种特殊的内部类,这种类没有名字,通过new关键字直接创建某一个类的匿名子类的对象来使用。

    以下情况需要用到匿名类:

    1. 只用到类的一个实例。
    2. 类在定义后马上用到。
    3. 类非常小,通常5行代码之内。
    4. 给类命名不会导致代码更容易被理解。

    但是需要注意:匿名内部类不能定义构造方法,并且功能上会受到很大的限制,如果不是很有必要,尽量不要去使用

     


    三、总结

     

    以上就是Java四种内部类的常见用法。


    1.成员内部类,就是内部类作为一个成员,存在于类中。

    实例化方法:   外部类.内部类 内部类对象 = new 外部类().new 内部类();


    2.静态内部类,在成员内部类的基础上,多了一个static关键字,是静态的类,所有的对象都可以直接通过类名调用。

    实例化方法:   内部类 内部类对象 = new new 内部类();


    3.方法内部类,在类的方法中,定义内部类。

    实例化方法:   new 内部类().内部类方法();   注意只能在当前方法中实例化。


    4.匿名内部类,直接new一个没有名字的类,并且直接调用其中的方法。

    实例化方法:    new 内部类(){ ...... }.内部类中的方法();


    参考文献:《Java语言面向对象程序设计(第二版)》 清华大学出版社

    展开全文
  • Java的内部类及其创建方式

    千次阅读 2018-11-20 10:14:52
    内部类及其创建方式 引言 在定义类时,我们可以将一个类定义在另一个类...在一开始,内部类看起来可能想hi是一种代码的隐藏机制,仅仅是用来将类的定义放置在其他的类的内部,但是,随着对于内部类的不断了解,我...

    内部类及其创建方式

    引言

    在定义类时,我们可以将一个类定义在另一个类的内部,此时这个类便被成为内部类。

    内部类是一种非常有用的特性,因为它允许你吧一些逻辑相关的类组织在一起,并控制位于内部的类的可视性。然而必须要了解,内部类与组合是两种完全不同地方概念,这一点很重要。

    在一开始,内部类看起来可能想hi是一种代码的隐藏机制,仅仅是用来将类的定义放置在其他的类的内部,但是,随着对于内部类的不断了解,我们会发现其远不止如此,它能够了解定义它的外部类,并能与之通信,利用内部类的种种特点,我们可以将代码变得更加优雅和清晰。

    基本的内部类的创建方式

    正如上面对于内部类的定义一样,当把一个类的定义置于另一个类的内部时,我们便完成了一个内部类的创建。

    在下面,我们假设创建了一个披萨店的类,在其中定义了两个内部类,分别为奶酪披萨cheesePizza与香肠披萨sausagePizza。

    package learning_java.InnerClassTest;
    
    public class PizzaStore {
        class cheesePizza {
            private String name = "cheesePizza";
            public void getName() {System.out.println("Got a " + name);}
        }
        class sausagePizza {
            private String name = "sausagePizza";
            public void getName() {System.out.println("Got a " +name);}
        }
        // 只有在该外部类的非静态方法中,才可以这样直接创建内部类的对象
        public void orderPizza(String pizzaName) {
            if (pizzaName == "cheesePizza") {
                cheesePizza pizza = new cheesePizza();
                pizza.getName();
            }
            else if (pizzaName == "sausagePizza"){
                sausagePizza pizza = new sausagePizza();
                pizza.getName();
            }
            else
                System.out.println("Don't have this kind of pizza");
        }
    
        public static void main(String[] args) {
            PizzaStore store = new PizzaStore();
            store.orderPizza("cheesePizza");
    
        }
    }
    

    在定义了两个披萨的内部类之后,我们又定义了一个订披萨的方法orderPizza,在这个方法里,我们会根据所输入的需要来创建披萨的对象。而我们在这个方法里面使用内部类的时候,看起来似乎与普通类并没有什么不同,在这里,实际的区别只是内部类的定义时嵌套在PizzaStore类里面的,但是接下来我们会看到,这并不是唯一的区别。

    public class PizzaStore2 {
        class cheesePizza {
            private String name = "cheesePizza";
            int size;
            cheesePizza(int inputSize){
                size = inputSize;
            }
            public void getName() {System.out.println("Got a " + name + "\tof size:\t" + size);}
        }
        class sausagePizza {
            private String name = "sausagePizza";
            int size;
            sausagePizza(int inputSize){
                size = inputSize;
            }
            public void getName() {System.out.println("Got a " + name + "\tof size:\t" + size);}
        }
    
        public sausagePizza getSausagePizza(int size){
            return new sausagePizza(size);
        }
        public cheesePizza getCheesePizza(int size){
            return new cheesePizza(size);
        }
        public void orderPizza(String pizzaName) {
            if (pizzaName == "cheesePizza") {
                cheesePizza pizza = new cheesePizza(5);
                pizza.getName();
            }
            else if (pizzaName == "sausagePizza"){
                sausagePizza pizza = new sausagePizza(5);
                pizza.getName();
            }
            else
                System.out.println("Don't have this kind of pizza");
        }
        // 如果想从外部类的非静态方法之外的任意位置创建某个内部类的对象,那么必须像在main()方法中这样,具体地知名这个对象的类型:OuterClassName.InnerClassName
        public static void main(String[] args) {
            PizzaStore2 store = new PizzaStore2();
            store.orderPizza("cheesePizza");
    
            PizzaStore2 store2 = new PizzaStore2();
            PizzaStore2.cheesePizza pizza = store2.getCheesePizza(6);
            pizza.getName();
        }
    }
    

    在上面的代码中,我们为两个披萨写了其构造函数,并用getCheesePizzagetSausagePizza方法来返回这两个披萨的实例,而我们在main()中声明其的时候用的是PizzaStore2.cheesePizza。与这个定义类似,对于内部类,如果想从外部类的非静态方法之外的任意位置创建某个内部类的对象,那么必须像在main()方法中这样,具体地知名这个对象的类型:OuterClassName.InnerClassName。即,即使定义该外部类的内部类的静态方法也不行,除该外部类之外的所有类都不可以。

    举个例子,如果在我们的披萨商店pizzaStore2中加入如下方法,可以看到其创建实例的方式与之前orderPizza方法是完全相同的。

    public static void test() {
            cheesePizza pizza = new cheesePizza(5);
    }
    

    此时便会报错:

    Error:(29, 29) java: 无法从静态上下文中引用非静态 变量 this
    

    内部类与外部类的链接

    到目前位置,内部类似乎还只是一种组织代码的模式,但是我们马上就能看到它的别的用途。当我们生成一个内部类的对象的同时,此对象与制造它的外围对象(enclosing object)之间就有了一个一种联系,这种联系使得它能够访问其外围对象的所有成员,而不需要任何特殊条件。此外,不仅于外围对象,内部类还拥有其外围类的所有元素的访问权。

    public class PizzaStore3 {
        private int materialsNum;
        private static int storeNum = 0;
        private static int allPizzaNum = 0;
        public void showMaterialsNum() {System.out.println("the num of materials:\t" + materialsNum);}
        public static void showStoreNum() {System.out.println("the num of store:\t" + storeNum);}
        public static void showAllPizzaNum() {System.out.println("the num of all the pizza:\t" + allPizzaNum);}
        public PizzaStore3(int materialsNum) {
            this.materialsNum = materialsNum;
            storeNum ++;
        }
        class cheesePizza implements Pizza{
            private String name = "cheesePizza";
            int size;
            cheesePizza(int inputSize){
                size = inputSize;
                materialsNum -= size;
                allPizzaNum ++;
            }
            public void getName() {System.out.println("Got a " + name + "\tof size:\t" + size);}
        }
        class sausagePizza implements Pizza{
            private String name = "sausagePizza";
            int size;
            sausagePizza(int inputSize){
                size = inputSize;
                materialsNum -= size;
                allPizzaNum ++;
            }
            public void getName() {System.out.println("Got a " + name + "\tof size:\t" + size);}
        }
    
        public sausagePizza getSausagePizza(int size){
            return new sausagePizza(size);
        }
        public cheesePizza getCheesePizza(int size){
            return new cheesePizza(size);
        }
    
        public void orderPizza(String pizzaName) {
            Pizza pizza;
            switch(pizzaName) {
                case "cheesePizza": pizza = new cheesePizza(5);break;
                case "sausagePizza": pizza = new sausagePizza(5);   break;
                default:    System.out.println("Don't have this kind of pizza"); return;
            }
            pizza.getName();
        }
        public static void main(String[] args) {
            PizzaStore3 store = new PizzaStore3(100);
    
            store.showMaterialsNum();
            PizzaStore3.showAllPizzaNum();
    
            PizzaStore3.cheesePizza pizza = store.getCheesePizza(6);
            pizza.getName();
    
            store.showMaterialsNum();
            PizzaStore3.showAllPizzaNum();
        }
    }
    

    在这里,我们依然以我们的披萨店为例,这一次,我们给每个披萨店增加了一个int类型的成员materialsNum来记录店里的原料的数量,而我们每制作一个披萨就会消耗与其大小相同数量的原料,同时为我们的PizzaStore3类增加了一个静态变量allPizzaNum来记录我们所有的披萨店所制作的披萨的数量,每当我们调用披萨的构造函数制作出一张披萨时,我们就在这个全局的数量上加一。

    之后,我们在main()中新建了一个store,并在store中制作了一个pizza,我们将以上的信息打印出来:

    the num of materials:	100
    the num of all the pizza:	0
    Got a cheesePizza	of size:	6
    the num of materials:	94
    the num of all the pizza:	1
    

    可以看到,无论对于对象的成员,还是类的静态成员,内部类都可以与其进行房访问并进行修改。当我们仔细查看内部类cheesePizzasausagePizza时,其构造函数都用到了变量materials,而这个变量并不是属于这两个内部类的,而是属于外围类pizzaStoreprivate字段,这里其实是一个引用,这使得内部类可以访问外围类的方法和字段,就像自己拥有它们似的,这带来了很大的方便。

    所有内部类自动拥有对其外围类所有成员的访问权,但是这是如何做到的呢?其实,当某个外围类的对象创建了一个内部类的对象时,此内部类对象必定会秘密地捕获一个指向那个外围类对象的引用,然后,在访问词外围类的成员时,就是用那个引用来选择外围类的成员。而这一系列过程中,编译器会帮助我们处理所有的细节,但现在可以看到,内部类的对象只能在与其外围类的对象的关联的情况下才能被创建(当内部类不是static时),构建一个内部类的对象时,需要一个指向其外围类的对象的引用,如果编译器访问不到这个引用,就会报错。而内部类与其外围类的这种关系,便引出了我们的下一节的内容。

    通过.this来在内部类中引用其外围类

    如上一节中所讲,一个外部类中的内部类的对象,是与这个外部类的对象存在着一个链接的依存关系的,那么我们是不是可以在内部类中显式地调起这个外部类的对象呢?答案是肯定的。如果我们在内部类中生成对于外围类对象的引用,可以使用外部类的名字后面紧跟.this,这样产生的引用自动对地具有正确的类型,这一点在编译期就会被知晓并受到检查,因此没有任何运行时的开销。我们在以下这个简化的披萨商店的类中来展示这一点。

    public class PizzaStore4 {
        void getStoreName() {System.out.println("PizzaStore4!");}
        public class CheesePizza {
            public PizzaStore4 getStore() {
                // 在这里通过.this来引用其外围类
                return PizzaStore4.this;
            }
        }
        public CheesePizza cheesePizza() {return new CheesePizza();}
    
        public static void main(String[] args) {
            PizzaStore4 store = new PizzaStore4();
            PizzaStore4.CheesePizza pizza = store.cheesePizza();
            pizza.getStore().getStoreName();
        }
    }
    

    输出:

    PizzaStore4!
    

    通过.new来创建内部类的对象

    在第一节中,当我们创建内部类的对象时,用的都是外部类中提供的可以返回一个新的内部类的对象的方法,如getCheesePizzagetSausagePizza,而外部类中并不总是提供这样的方法,那么我们怎样直接得到一个内部类的对象呢?

    正如内部类与外部类的对象的链接一节中所讲,每个内部类都是与其外部类的一个对象相链接的,因此在创建内部类的对象时,也需要体现出这一点,我们是不能够直接new一个内部类的对象出来的,那如何与外部类的对象产生关联呢?这里,我们就需要使用.new语法了,下面这个例子会介绍这个语法的使用方法。

    public class PizzaSotre5 {
        public class CheesePizza{}
        public static void main(String[] args) {
            PizzaSotre5 store = new PizzaSotre5();
            // 通过.new来创建内部类的对象
            PizzaSotre5.CheesePizza pizza = store.new CheesePizza();
        }
    }
    

    由于我们是直接用PizzaStore来创建的内部类对象pizza,因此这样便直接解决了内部类对象与外部类对象的链接与内部类对象的作用域问题。实际上,这里我们不能去引用外部类的名字PizzaStore5,而必须用对象来创捷内部类对象,我们不必也不能store.new PizzaStore5.CheesePizza()

    由此,我们可以看到,在拥有外部类的对象之前,是不饿能创建内部类的对象的。这是因为内部类对象会自动地连接到创建它的外部类的对象上。但是,如果我们创建的是嵌套类(静态内部类),那么它就不需要对外部类对象的引用。

    展开全文
  • 1. Java的内部类机制 所谓内部类,是指在一个类的内部还有另外一个类的定义. 在Java中,可以在类的内部定义内部类, 也可以在方法内部定义一个类. 对于第一种形式,即类的内部定义一个新类,比较简单,举例如下: ? ...
  • 一题引出“Java的内部类

    千次阅读 2021-04-14 20:33:58
    在下面插入哪段代码可以获得一个Point对象坐标?( ) A、Point p = Line.getPoint(); B、Line.Point p = Line.getPoint(); C、Point p = (new Line()).getPoint(); D、Line.Point p = (new Line()).getPoint(); ...
  • 1. 静态的内部类称为嵌套类,嵌套类
  • 文章目录1 内部类的基本概念1.1 内部类的定义1.2 内部类的优缺点2 创建内部类2.1 在外部类外部创建非静态内部类2.2 在外部类外部创建静态内部类2.3 在外部类内部创建内部类语法3 内部类的分类3.1 成员内部类3.2 静态...
  • Java内部类和匿名内部类的用法

    万次阅读 多人点赞 2016-07-21 15:46:41
    Java内部类和匿名内部类的用法 【尊重原创,转载请注明出处】http://blog.csdn.net/guyuealian/article/details/51981163一、内部类: (1)内部类的同名方法 内部类可以调用外部类方法,如果内部类有同名方法...
  • 详解 Java 内部类

    万次阅读 多人点赞 2018-09-04 00:17:56
    前言 内部类在 Java 里面算是非常常见的一个功能了,在日常开发中我们肯定多多少少都用过,这里...这个是最常见的内部类之一了,其定义也很简单,在一个类里面作为类的一个字段直接定义就可以了,例: pub...
  • java 内部类

    千次阅读 2015-12-23 14:52:25
    java的内部类 顾名思义就是定义在java类里面的内部类 下面看一个简单的例子 public class Father { /* * Son 是内部类 */ public class Son { public void eat() { System.out.println("eating"); }...
  • java 静态内部类的使用

    万次阅读 2018-11-05 19:06:39
    java 静态内部类的使用
  • JAVA内部类的继承和覆盖问题

    千次阅读 2017-07-26 10:31:14
    JAVA的内部类继承与覆盖问题还是有一些细节方面需要注意的地方
  • 首先我们看下RecyclerViewViewHolder写法,java和kotlin分别用静态内部类进行实现,代码是随意找java静态内部类: static class EndViewHolder extends BlocksView.ViewHolder { public ...
  • Java内部类

    千次阅读 2019-05-02 02:28:01
    成员内部类:声明一个新 class 类,作为该类一个成员 局部内部类:在一个方法内部,重新声明一个类 静态内部类:static 修饰内部类 匿名内部类java提高篇-----详解匿名内部类 :...
  • java内部类的定义、内部类的分类

    千次阅读 2021-04-24 10:05:33
    内部类 基本介绍 一个类的内部又完整的嵌套了另一个类结构。被嵌套的类称为内部类(inner class),嵌套其他类的类称为外部类(outer class)。是我们类的第五大成员,内部类最大的特点就是可以直接访问私有属性,并且...
  • java内部类

    2011-11-21 17:06:54
    之前本科阶段学java一直对java的内部类使用方法掌握的不好,最近学Android开发,监听器大量使用了内部类,故做点小总结。 内部类,就是一个类在另一个类的内部,这种方法在java中比较常见,比如在编写多线程程序的...
  • JAVA内部类
  • java内部类的作用是神马 java内部类的作用是神马 java内部类的作用是神马
  • 内部类(Inner Class)和静态内部类(Static Nested Class)区别: 定义在一个类内部类叫内部类,包含内部类的类称为外部类。内部类可以声明public、protected、private等访问限制,可以声明 为abstract供其他...
  • java局部内部类和匿名内部类

    千次阅读 2019-06-16 11:46:28
    java局部内部类就是在方法中定义类,它仅在该方法中有效。因为它不能在该方法之外使用,因此它不能使用访问控制符和static修饰。它应用场景是:在java代理模式中,可以直接在方法中用局部内部类实现某些接口或...
  • java匿名内部类什么是匿名内部类?匿名内部类的使用场景?匿名内部类如何创建?匿名内部类的实现和使用例1(实现接口)例2(继承类) 什么是匿名内部类? 匿名内部类,顾名思义,就是不知道这个类到底是什么名字,也...
  • JAVA的内部类

    千次阅读 2021-03-13 00:57:39
    JAVA的内部类 内部类分为: 成员内部类,静态内部类,局部内部类,匿名内部类 内部类:在一个类的内部再定义一个完整的类; 各种内部类的特点: 1.成员内部类: 1.编译之后可分别生成独立的字节码文件(.class),是两个独立...
  • Java的内部类和C++中的嵌套类有本质的不同:C++的嵌套类没有指向包装类的句柄。仅仅表达一个封装的概念;但是Java的内部类不同,它可以访问包装类的成员(这表示它拥有指向包装类的句柄)。 匿名内部类是内部类的...
  • java的内部类内部接口详解

    千次阅读 2020-05-08 06:24:42
    一般来说,我们创建类和接口的时候都是一个类一个文件,一个接口一个文件,但有时候为了方便或者某些特殊的原因,java并不介意在一个文件中写多个类和多个接口,这就有了我们今天要讲的内部类和内部接口。...
  • Java-内部类

    千次阅读 2020-07-05 21:19:52
    内部类的class文件形式:Outer$Inner.class(编译后会产生两个类,外部类和内部类) 内部类对象实例化:Outer.Inner in = new Outer().new Inner(); 公式:外部类名称.内部类名称 内部类对象名称 = new 外部类().new...
  • Java 静态内部类内部类区别

    千次阅读 2018-05-30 10:52:37
    静态内部类的作用:只是为了降低包深度,方便类使用,静态内部类适用于包含类当中,但又不依赖于外在类,不用使用外在类非静态属性和方法,只是为了方便管理类结构而定义。在创建静态内部类的时候,不需要...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 60,993
精华内容 24,397
关键字:

java的内部类

java 订阅