Java学习笔记-内部类
内部类在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修饰的
- 内部类的使用:
- 在外部类中使用内部类
- 在外部类中以外使用非静态内部类
- 此时内部类不可使用private修饰
OuterClass.InnerClass varNameOuterInstance.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");
}
}
- 在外部类以外使用静态内部类
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 外部类名或者接口名(){覆盖类或者接口中的代码,(也可以自定义内)}
简单理解:
- 就是建立一个建立一个带内容的外部类或者接口的子类匿名对象
- 匿名内部类其实就是内部类的简写格式
- 定义匿名内部类的前提:内部类必须是继承一个类或者实现接口
- 匿名内部类的格式:
new 父类或者接口(){定义子类的内容} - 其实匿名内部类就是一个匿名子类对象。可以理解为带内容的对象
- 匿名内部类中定义的方法最好不要超过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修饰
Java学习笔记-内部类的更多相关文章
- Java学习笔记——内部类及其调用方法
一.static内部类的static方法 public class Test0719_Inner_Test { public static void main(String[] args) { //s ...
- Java学习笔记之---内部类
Java学习笔记之---内部类 (一)成员内部类 内部类在外部使用时,无法直接实例化,需要借助外部类信息才能实例化 内部类的访问修饰符可以任意,但是访问范围会受到影响 内部类可以直接访问外部类的成员, ...
- 0035 Java学习笔记-注解
什么是注解 注解可以看作类的第6大要素(成员变量.构造器.方法.代码块.内部类) 注解有点像修饰符,可以修饰一些程序要素:类.接口.变量.方法.局部变量等等 注解要和对应的配套工具(APT:Annot ...
- 0028 Java学习笔记-面向对象-Lambda表达式
匿名内部类与Lambda表达式示例 下面代码来源于:0027 Java学习笔记-面向对象-(非静态.静态.局部.匿名)内部类 package testpack; public class Test1{ ...
- 《Java学习笔记(第8版)》学习指导
<Java学习笔记(第8版)>学习指导 目录 图书简况 学习指导 第一章 Java平台概论 第二章 从JDK到IDE 第三章 基础语法 第四章 认识对象 第五章 对象封装 第六章 继承与多 ...
- 0013 Java学习笔记-面向对象-static、静态变量、静态方法、静态块、单例类
static可以修饰哪些成员 成员变量---可以修饰 构造方法---不可以 方法---可以修饰 初始化块---可以修饰 内部类(包括接口.枚举)---可以修饰 总的来说:静态成员不能访问非静态成员 静 ...
- Java学习笔记4
Java学习笔记4 1. JDK.JRE和JVM分别是什么,区别是什么? 答: ①.JDK 是整个Java的核心,包括了Java运行环境.Java工具和Java基础类库. ②.JRE(Java Run ...
- 【Java学习笔记之二十六】深入理解Java匿名内部类
在[Java学习笔记之二十五]初步认知Java内部类中对匿名内部类做了一个简单的介绍,但是内部类还存在很多其他细节问题,所以就衍生出这篇博客.在这篇博客中你可以了解到匿名内部类的使用.匿名内部类要注意 ...
- java学习笔记9--内部类总结
java学习笔记系列: java学习笔记8--接口总结 java学习笔记7--抽象类与抽象方法 java学习笔记6--类的继承.Object类 java学习笔记5--类的方法 java学习笔记4--对 ...
随机推荐
- 201812-4 数据中心(kruskal)
考场上的时候被题目完全蒙住了,当时状态也不好,前几次考试每次考试当天就头晕感冒流鼻涕 好的,以上都是借口,自己没有好好复习才是真的... 题目: 好的,以上题目简述就是:给你一个无向连通图,求它的最小 ...
- SqlHelper发布—比Pagehelper更好用的分页插件
SqlHelper发布-比PageHelper性能更高 起源 前段时间开启了一个新的项目,在选择分页插件时,发现github上很流行的一个是pagehelper,在百度上搜索了一下,使用量.由于项目紧 ...
- Codeforces Round #584 E2. Rotate Columns (hard version)
链接: https://codeforces.com/contest/1209/problem/E2 题意: This is a harder version of the problem. The ...
- Centos7下Nexus3的安装和配置
参考文档:https://help.sonatype.com/repomanager3 1.要使用nexus服务需要安装jdk和maven 1.1.jdk下载地址:https://www.oracle ...
- Vue项目开发最新、最全代码规范文档
Vue项目开发最新.最全代码规范文档 2019年02月21日 10:43:49 yw00yw 阅读数 337 一. 目录结构 |— build 构建脚本目录 |— build.js 生产环境构建( ...
- PC端使用program來CHGUSRPRF
執行CHGUSRPRF命令需要*SECADM 權限,但通常Security部門不允許Grant這個這麼大的權限,爲了達到目的,改用下面的方法 1. Create CL program 注意裏面一定要用 ...
- [Luogu] 跑路
https://www.luogu.org/problemnew/show/P1613 Floyd判断是否一步到达 将一步到达的连变跑Floyd #include <iostream> # ...
- 「CF484E」Sign on Fence「整体二分」「线段树」
题意 给定一个长度为\(n\)的正整数序列,第\(i\)个数为\(h_i\),\(m\)个询问,每次询问\((l, r, w)\),为\([l, r]\)所有长度为\(w\)的子区间最小值的最大值.( ...
- codeforces 1272F dp+记录路径
题意 给出两个括号序列 \(S\) 和 \(T\),让你构造一个最短的合法括号序列使 \(S\) 和 \(T\) 是它的子序列. 分析 设 \(dp[i][j][k]\) 为这个最短的合法括号序列的前 ...
- UVALive 4976 Defense Lines ——(LIS变形)
题意:给出序列,能够从这序列中删去连续的一段,问剩下的序列中的最长的严格上升子串的长度是多少. 这题颇有点LIS的味道.因为具体做法就是维护一个单调的集合,然后xjbg一下即可.具体的见代码吧: #i ...