10(02)总结形式参数,包,修饰符,内部类

6:内部类(理解)

(1)把类定义在另一个类的内部,该类就被称为内部类。

举例:把类B定义在类A中,类B就被称为内部类。

(2)内部类的访问规则

A:可以直接访问外部类的成员,包括私有

B:外部类要想访问内部类成员,必须创建对象

/*

内部类概述:

把类定义在其他类的内部,这个类就被称为内部类。

举例:在类A中定义了一个类B,类B就是内部类。

内部的访问特点:

A:内部类可以直接访问外部类的成员,包括私有。

B:外部类要访问内部类的成员,必须创建对象。

*/
class Outer {
 private int num = 10;
 class Inner {
 public void show() {
 System.out.println(num);
 }
 }
 public void method() {
 //找不到符号
 //show();
 Inner i = new Inner();
 i.show();
 }
}
class InnerClassDemo {
 public static void main(String[] args) {
 }
}

(3)内部类的分类

A:成员内部类

B:局部内部类

/*
 内部类位置
 成员位置:在成员位置定义的类,被称为成员内部类。 
 局部位置:在局部位置定义的类,被称为局部内部类。
 成员位置:在成员位置定义的类,被称为成员内部类。 
*/
class Outer {
 private int num = 10;
 //成员位置
 /*
 class Inner {
 }
 */
 public void method() {
 //局部位置
 class Inner {
 }
 }
}
class InnerClassDemo2 {
 public static void main(String[] args) {
 }
}

(4)成员内部类

A:private 为了数据的安全性

B:static 为了访问的方便性

成员内部类不是静态的:

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

成员内部类是静态的:

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

/*
 成员内部类:
 如何直接访问内部类的成员。
 外部类名.内部类名 对象名 = 外部类对象.内部类对象;
*/
class Outer {
 private int num = 10;
 class Inner {
 public void show() {
 System.out.println(num);
 }
 }
}
class InnerClassDemo3 {
 public static void main(String[] args) {
 //需求:我要访问Inner类的show()方法
 //Inner i = new Inner();
 //i.show();
 //格式:外部类名.内部类名 对象名 = 外部类对象.内部类对象;
 Outer.Inner oi = new Outer().new Inner();
 oi.show();
 }
}
/*
 成员内部类的修饰符:
 private 为了保证数据的安全性
 static 为了方便访问数据
 注意:静态内部类访问的外部类数据必须用静态修饰。
 案例:我有一个人(人有身体,身体内有心脏。)
 class Body {
 private class Heart {
 public void operator() {
 System.out.println("心脏搭桥");
 }
 }
 public void method() {
 if(如果你是外科医生) {
 Heart h = new Heart();
 h.operator();
 }
 }
 }

按照我们刚才的讲解,来使用一下

 Body.Heart bh = new Body().new Heart();
 bh.operator();
 //加了private后,就不能被访问了,那么,怎么玩呢?
 Body b =  new Body();
 b.method();
*/
class Outer {
 private int num = 10;
 private static int num2 = 100;
 //内部类用静态修饰是因为内部类可以看出是外部类的成员
 public static class Inner {
 public void show() {
 //System.out.println(num);
 System.out.println(num2);
 }
 public static void show2() {
 //System.out.println(num);
 System.out.println(num2);
 } 
 }
}
class InnerClassDemo4 {
 public static void main(String[] args) {
 //使用内部类
 // 限定的新静态类
 //Outer.Inner oi = new Outer().new Inner();
 //oi.show();
 //oi.show2();
 //成员内部类被静态修饰后的访问方式是:
 //格式:外部类名.内部类名 对象名 = new 外部类名.内部类名();
 Outer.Inner oi = new Outer.Inner();
 oi.show();
 oi.show2();
 //show2()的另一种调用方式
 Outer.Inner.show2();
 }
}

(5)成员内部类的面试题(填空)

 30,20,10
 class Outer {
 public int num = 10;
 class Inner {
 public int num = 20;
 public viod show() {
 int num  = 30;
 System.out.println(num);
 System.out.println(this.num);
 System.out.println(Outer.this.num);
 }
 }
 }
/* 面试题:
 要求请填空分别输出30,20,10。
 注意:
 1:内部类和外部类没有继承关系。
 2:通过外部类名限定this对象
 Outer.this
*/
class Outer {
 public int num = 10;
 class Inner {
 public int num = 20;
 public void show() {
 int num = 30;
 System.out.println(num);
 System.out.println(this.num);
 //System.out.println(new Outer().num);
 System.out.println(Outer.this.num);
 }
 }
}
class InnerClassTest {
 public static void main(String[] args) {
 Outer.Inner oi = new Outer().new Inner();
 oi.show();
 } 
}

(6)局部内部类

A:局部内部类访问局部变量必须加final修饰。

B:为什么呢?

因为局部变量使用完毕就消失,而堆内存的数据并不会立即消失。

所以,堆内存还是用该变量,而改变量已经没有了。

为了让该值还存在,就加final修饰。

通过反编译工具我们看到了,加入final后,堆内存直接存储的是值,而不是变量名。

/*
 局部内部类
 A:可以直接访问外部类的成员
 B:在局部位置,可以创建内部类对象,通过对象调用内部类方法,来使用局部内部类功能
 面试题:
 局部内部类访问局部变量的注意事项?
 A:局部内部类访问局部变量必须用final修饰
 B:为什么呢?
 局部变量是随着方法的调用而调用,随着调用完毕而消失。
 而堆内存的内容并不会立即消失。所以,我们加final修饰。
 加入final修饰后,这个变量就成了常量。既然是常量。你消失了。
 我在内存中存储的是数据20,所以,我还是有数据在使用。
*/
class Outer {
 private int num  = 10;
 public void method() {
 //int num2 = 20;
 //final int num2 = 20;
 class Inner {
 public void show() {
 System.out.println(num);
 //从内部类中访问本地变量num2; 需要被声明为最终类型
 System.out.println(num2);//20
 }
 }
 //System.out.println(num2);
 Inner i = new Inner();
 i.show();
 }
}
class InnerClassDemo5 {
 public static void main(String[] args) {
 Outer o = new Outer();
 o.method();
 }
}

(7)匿名内部类(掌握)

A:是局部内部类的简化形式

B:前提

存在一个类或者接口

C:格式:

new 类名或者接口名() {

重写方法;

}

D:本质:

其实是继承该类或者实现接口的子类匿名对象

/*
 匿名内部类
 就是内部类的简化写法。
 前提:存在一个类或者接口
 这里的类可以是具体类也可以是抽象类。
 格式:
 new 类名或者接口名(){
 重写方法;
 }
 本质是什么呢?
 是一个继承了该类或者实现了该接口的子类匿名对象。
*/
interface Inter {
 public abstract void show();
 public abstract void show2();
}
class Outer {
 public void method() {
 //一个方法的时候
 /*
 new Inter() {
 public void show() {
 System.out.println("show");
 }
 }.show();
 */
 //二个方法的时候
 /*
 new Inter() {
 public void show() {
 System.out.println("show");
 }
 public void show2() {
 System.out.println("show2");
 }
 }.show();
 new Inter() {
 public void show() {
 System.out.println("show");
 }
 public void show2() {
 System.out.println("show2");
 }
 }.show2();
 */
 //如果我是很多个方法,就很麻烦了
 //那么,我们有没有改进的方案呢?
 Inter i = new Inter() { //多态
 public void show() {
 System.out.println("show");
 }
 public void show2() {
 System.out.println("show2");
 }
 };
 i.show();
 i.show2();
 }
}
class InnerClassDemo6 {
 public static void main(String[] args) {
 Outer o = new Outer();
 o.method();
 }
}

(8)匿名内部类在开发中的使用

我们在开发的时候,会看到抽象类,或者接口作为参数。

而这个时候,我们知道实际需要的是一个子类对象。

如果该方法仅仅调用一次,我们就可以使用匿名内部类的格式简化。

 interface Person {
 public abstract void study();
 }
 class PersonDemo {
 public void method(Person p) {
 p.study();
 }
 }
 class PersonTest {
 public static void main(String[] args) {
 PersonDemo pd = new PersonDemo();
 pd.method(new Person() {
 public void study() {
 System.out.println("好好学习,天天向上");
 }
 });
 }
 }
/*
 匿名内部类在开发中的使用
*/
interface Person {
 public abstract void study();
}
class PersonDemo {
 //接口名作为形式参数
 //其实这里需要的不是接口,而是该接口的实现类的对象
 public void method(Person p) {
 p.study();
 }
}
//实现类
class Student implements Person {
 public void study() {
 System.out.println("好好学习,天天向上");
 }
}
class InnerClassTest2 {
 public static void main(String[] args) {
 //测试
 PersonDemo pd = new PersonDemo();
 Person p = new Student();
 pd.method(p);
 System.out.println("--------------------");
 //匿名内部类在开发中的使用
 //匿名内部类的本质是继承类或者实现了接口的子类匿名对象
 pd.method(new Person(){
 public void study() {
 System.out.println("好好学习,天天向上");
 }
 });
 }
}

(9)匿名内部类的面试题(补齐代码)

 interface Inter {
 void show();
 }
 class Outer {
 //补齐代码
 public static Inter method() {
 return new Inter() {
 public void show() {
 System.out.println("HelloWorld");
 } 
 };
 }
 }
 class OuterDemo {
 public static void main(String[] args) {
 Outer.method().show(); //"HelloWorld"
 }
 }
/*
 匿名内部类面试题:
 按照要求,补齐代码
 interface Inter { void show(); }
 class Outer { //补齐代码 }
 class OuterDemo {
 public static void main(String[] args) {
   Outer.method().show();
   }
 }
 要求在控制台输出”HelloWorld”
*/
interface Inter { 
 void show(); 
 //public abstract
}
class Outer { 
 //补齐代码
 public static Inter method() {
 //子类对象 -- 子类匿名对象
 return new Inter() {
 public void show() {
 System.out.println("HelloWorld");
 }
 };
 }
}
class OuterDemo {
 public static void main(String[] args) {
 Outer.method().show();
 /*
 1:Outer.method()可以看出method()应该是Outer中的一个静态方法。
 2:Outer.method().show()可以看出method()方法的返回值是一个对象。
 又由于接口Inter中有一个show()方法,所以我认为method()方法的返回值类型是一个接口。
 */
 }
}

原文发布于微信公众号 - Java帮帮(javahelp)

原文发表时间:2016-11-30

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏大数据-Hadoop、Spark

Scala学习一

1.集合操作练习 //创建一个List val lst0 = List(1,7,9,8,0,3,5,4,6,2) //将lst0中每个元素乘以10后生成一个新的...

59260
来自专栏黑泽君的专栏

java基础学习_基础语法(上)03_day04总结

============================================================================= ==...

11410
来自专栏技术沉淀

Python: collections模块实例透析Collections模块

19680
来自专栏Micro_awake web

JavaScript(四):运算符&数据类型转换

+:算符的加法;连接字符串 加法会将其它类型的值,自动转为字符串,然后再进行连接运算! 1 var a=1+2; 2 console.log('first:...

20460
来自专栏转载gongluck的CSDN博客

python笔记:#005#算数运算符

算数运算符 计算机,顾名思义就是负责进行 数学计算 并且 存储计算结果 的电子设备 目标 算术运算符的基本使用 01. 算数运算符 算数运算符是 运算符的一种 ...

39170
来自专栏程序员互动联盟

【答疑解惑】Java中重载和重写的区别

今天群里有网友搞不清楚一个问题: ? 重载和重写属于Java面向对象中多态基础知识点,下面就给大家说说多态。 什么叫做多态? 多态指的是在继承关系中子类继承父类...

31070
来自专栏电光石火

没有任何类型 Windows 的外层实例可访问---Java内部类与外类型

Java内部类与外部类 错误提示: 没有任何类型 TestThread 的外层实例可访问。必须用类型 TestThread 的外层实例(例如,x....

39880
来自专栏猿人谷

扑克牌的顺子

题目:从扑克牌中随机抽5张牌,判断是不是一个顺子,即这5张牌是不是连续的。2~10为数字本身,A为1,J为11,Q为12,K为13,而大、小王可以看成任意数字...

20090
来自专栏老马说编程

(21) 内部类的本质 / 计算机程序的思维逻辑

内部类 之前我们所说的类都对应于一个独立的Java源文件,但一个类还可以放在另一个类的内部,称之为内部类,相对而言,包含它的类称之为外部类。 为什么要放到别的...

22980
来自专栏C++

python笔记:#005#算数运算符

18520

扫码关注云+社区

领取腾讯云代金券