《day11---内部类&匿名内部类》
//79-80-面向对象-内部类-体现
/*
当A类中的内容要被B类直接访问,而A类还需要去创建B类的对象,访问B的内容时,
这时可以将B类定义到A类的内部,这样访问更为便捷。 将B类称之为内部类(内置类,嵌套类). 访问方式总结:
内部类可以直接访问外部类中的所有成员,包含私有的。
而外部类要想访问内部类中的成员,必须创建内部类对象。 当描述事物时,事物的内部还有事物时,而这个内部的事物还在访问外部事物中的内容。
这时就将这个事物通过内部类来体现。 【内部类被访问的方式】
情况一:内部类在成员位置上的被访问方式。
成员是可以被指定的修饰符所修饰的。
public :不多见,因为更多的时候,内部类已经被封装到了外部类中,不直接
对外提供。
static:
*/ class Outer//外部类
{
private static int num = 4; public class Inner//内部类
{
// static final int x = 3;
void show()
{
System.out.println("num="+num);
}
static void show1(){}//非静态内部类中不允许定义静态成员。仅允许在
//非静态内部类中定义常量。(final)
//如果想要在内部类中定义静态成员,那么内部类也必须
//别静态修饰。
} /*
内部类被静态修饰后,随着Outer的加载而加载,可以把一个静态内部类理解为就是一个外部类。
*/
static class Inner2
{
void show2()
{
System.out.println("Inner2 show2 run..."+num);
}
static void staticShow()
{
System.out.println("Inner2 staticShow run");
}
}
void method()
{
//Outer.Inner in = new Outer.Inner();//这样写也是可以的。
Inner in = new Inner();
in.show();
}
} class Inner
{
public static void main(String[] args)
{
// Outer out = new Outer();
// out.method(); //测试情况一:直接访问Outer类中的内部类的非静态成员。 //创建内部类的对象就可以了,内部类作为成员,应该先有外部类对象,再有内部类对象。
// Outer.Inner in = new Outer().new Inner();
// in.show(); //测试二:对静态内部类中的非静态成员进行调用,如何弄?
//因为内部类是静态,所以不需要创建Outer的对象,直接创建内部类对象就行了。
// Outer.Inner2 in = new Outer.Inner2();
// in.show2(); //如果静态内部类中有静态成员该如何访问呢?既然静态内部类已随外部类加载,而且
//静态成员随着类的加载而加载,这时就不需要对象,直接用类名调用即可。
Outer.Inner2.staticShow(); }
}
//81-面向对象内部类访问外部类的原因。
/*
为什么内部类就能直接访问外部类中的成员呢?
那是因为内部类持有了外部类的引用 外部类.this 对于静态内部类不持有 外部类.this 而是直接使用外部类名。
*/
class Outer
{
int num = 3; class Inner
{
int num = 4;
void show()
{
int num = 5;
System.out.println("num="+num);
System.out.println("num="+this.num);
System.out.println("num="+Outer.this.num);
}
}
void method()
{
//System.out.println(/*Outer.this.*/num);
new Inner().show();
}
}
class InnerClassDemo2
{
public static void main(String[] args)
{
Outer out = new Outer();
out.method();
}
}
/*
内部类其实也可以定义在外部类的局部变量位置上。 内部类定义在局部时,只能访问被final修饰的局部变量。
为啥呢?因为编译生成的class中直接操作那个最终的数值了。
所以可以访问final,因为其值不会变化。 为什么不能访问非最终的局部变量呢?
*/
class Outer
{
int num = 3;
// Object obj; void method()
{
int x = 5;//局部变量。省略的final修饰符。
// x = 4; //编译失败,因为x默认为final的。
int y = 3;
class Inner//局部内部类。不能被成员修饰符修饰。
{
void show()
{
System.out.println("x="+x);
System.out.println("x="+y);//若y没有加默认的final修饰符,则
//访问失败,因为y的声明周期太短了。
System.out.println("Inner show run..."+num);
}
}
new Inner.show();
// obj = new Inner();
}
} class Outer2
{
Object obj;
public void method()
{
int y = 9;
class Inner//extends Object
{
//覆盖了toString方法
public String toString()
{
return "tostring"+y;//假设可以访问。
}
}
obj = new Inner();//给obj赋一个Inner对象。
}
public void function()
{
System.out.println(obj.toString());
}
} class InnerClassDemo5
{
public static void main(String[] args)
{
Outer out = new Outer();
out.method();
}
}
//83-84内部类-内部类的继承或者实现&匿名内部类。
/*
看API,发现类名或者接口的名称中有 . 说明是内部类,或者内部接口。 内部了的延伸。
内部类是可以继承或者实现外部其他的类或者接口的。 好处在于,通过内部类的方式对类进行继承重写,或者接口进行实现。
通过公共的方式对其内部类对象进行访问,因为通常内部类很有可能被外部类封装其中。
我们就可以通过接口的方式访问到内部类。 对以下代码进行简化。
匿名内部类,其实就是一个带有内容的子类对象。
格式: new 父类or接口()(子类内容。) 匿名内部类就是内部类的简化形式。
别忘了,凡是简化的都有局限性。匿名内部类有前提,
匿名内部类必须继承父类或者实现接口。
*/ //定义一个抽象的外部类。
abstract class AbsDemo
{
abstract void show();
} class Outer
{
int num = 3;
/*
class Inner extends AbsDemo
{
//重写抽象方法show。
void show()
{
System.out.println("num="+num);
}
} //获取内部类的对象。
public AbsDemo getObject()//多态:AbsDemo abs = new Inner();
{
return new Inner();
}
*/
public void method()
{
// new Inner().show();
/*
不想创建具体的子类型,还想创建AbsDemo的子类对象。
怎么实现呢?没有子类型,干脆直接使用父类型就可以了。
可是在该例子中是抽象类,怎么可以new对象呢?
抽象类之所以不能new对象,是因为抽象方法没有被覆盖。只要
重写不就可以了吗?
*/
new AbsDemo()//这就是一个AbsDemo的子类对象。只不过这个对象有点胖。
//这是一个带着内容的子类对象。
//这种写法有一个称呼,叫做【匿名内部类】。
{
//直接就重写抽象的show方法。
void show()
{
System.out.println("num==="+num);
}
}.show();
}
} class InnerClassDemo4
{
public static void main(String[] args)
{
//Outer out = new Outer();
// out.method(); //如果Inner对外提供,可以如此获取。
//Outer.Inner in = out.getObject();
//in.show(); //如果Inner被private,可以通过父类型获取。
//AbsDemo a = out.getObject();
//a.show(); Outer out = new Outer();
out.method();
}
}
//86-内部类-匿名内部类的使用。
interface Inter
{
void show1();
void show2();
//方法超过两个,建议不要写成匿名内部类。
} class Outer
{
int num = 4; //在一个类中使用一个接口,可以通过内部类来实现。
/*
class Inner implements Inter
{
public void show1(){}
public void show2(){}
}
*/
public void method()
{
/*
Inner in = new Inner();
in.show1();
in.show2();
*/ //对其简化,写成匿名内部类的形式。
Inter in = new Inner()//多态,父类的引用指向了子类对象。
{
public void show1(){}
public void show2(){}
};
in.show1();
in.show2();
}
}
class InnerClassDemo5
{
public static void main(String[] args)
{
System.out.println("Hello World!");
}
}
//87-匿名内部类练习。
interface Inter
{
public void show();
} class Outer
{
//代码补足。要求使用匿名内部类。
public static Inter method()
{
//既然在Outer类中使用到了Inter对象,可以使用内部类来完成。
//需要子类型,只要简化形式即可,因为接口中就只有一个方法。 /*
return new Inter()
{
public void show()
{
code...;
}
};
*/
// return this.new Inter();
// } //还原成内部类。当静态方法访问内部类时,内部类必须是静态的。
/* static class Inner implements Inter
{
public void show(){}
}
*/
}
} //面试题:
class Outer2
{
public void method()
{
//以下两个对象有区别吗?
new Object()//当new Object();时,是创建Object对象,而写成new Object(){}时,创建
//的是Object的子类对象。
{
public void show(){}
}.show();//这个可以编译通过 Object obj = new Object()
{
public void show(){}
};
obj.show();//编译失败。为啥呢?因为匿名内部类是子类对象,当Object obj指向
//时,就被提升了,而Object类中没有定义show()方法。编译失败。 }
/*
//写一个内部类。
class Inner extends Object//有父类,可以简化成匿名内部类。
{
public void show(){}
}
*/
} class InnerClassDemo7
{
public static void main(String[] args)
{
Outer.method().show();
/*
Outer.method():Outer类中有一个method方法,这个方法时静态的。
Outer.method().show():能调用show()的必然是对象。说明method方法运算完应
该放回一个对象,而且能调用Inner中的方法,说明
这个对象类型是Inner的。
*/
}
}
《day11---内部类&匿名内部类》的更多相关文章
- 简单物联网:外网访问内网路由器下树莓派Flask服务器
最近做一个小东西,大概过程就是想在教室,宿舍控制实验室的一些设备. 已经在树莓上搭了一个轻量的flask服务器,在实验室的路由器下,任何设备都是可以访问的:但是有一些限制条件,比如我想在宿舍控制我种花 ...
- 利用ssh反向代理以及autossh实现从外网连接内网服务器
前言 最近遇到这样一个问题,我在实验室架设了一台服务器,给师弟或者小伙伴练习Linux用,然后平时在实验室这边直接连接是没有问题的,都是内网嘛.但是回到宿舍问题出来了,使用校园网的童鞋还是能连接上,使 ...
- 外网访问内网Docker容器
外网访问内网Docker容器 本地安装了Docker容器,只能在局域网内访问,怎样从外网也能访问本地Docker容器? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动Docker容器 ...
- 外网访问内网SpringBoot
外网访问内网SpringBoot 本地安装了SpringBoot,只能在局域网内访问,怎样从外网也能访问本地SpringBoot? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装Java 1 ...
- 外网访问内网Elasticsearch WEB
外网访问内网Elasticsearch WEB 本地安装了Elasticsearch,只能在局域网内访问其WEB,怎样从外网也能访问本地Elasticsearch? 本文将介绍具体的实现步骤. 1. ...
- 怎样从外网访问内网Rails
外网访问内网Rails 本地安装了Rails,只能在局域网内访问,怎样从外网也能访问本地Rails? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动Rails 默认安装的Rails端口 ...
- 怎样从外网访问内网Memcached数据库
外网访问内网Memcached数据库 本地安装了Memcached数据库,只能在局域网内访问,怎样从外网也能访问本地Memcached数据库? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装 ...
- 怎样从外网访问内网CouchDB数据库
外网访问内网CouchDB数据库 本地安装了CouchDB数据库,只能在局域网内访问,怎样从外网也能访问本地CouchDB数据库? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动Cou ...
- 怎样从外网访问内网DB2数据库
外网访问内网DB2数据库 本地安装了DB2数据库,只能在局域网内访问,怎样从外网也能访问本地DB2数据库? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动DB2数据库 默认安装的DB2 ...
- 怎样从外网访问内网OpenLDAP数据库
外网访问内网OpenLDAP数据库 本地安装了OpenLDAP数据库,只能在局域网内访问,怎样从外网也能访问本地OpenLDAP数据库? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动 ...
随机推荐
- C语言编译器 cc 编译原理
生成一个可执行的文件通常需要经过以下几个步骤: 预处理你的源代码,去掉注释,以及其他技巧性的工作就像在 C 中展开宏. 检查代码的语法看你是否遵守了这个语言的规则.如果没有,编译器会给出 警告. 把源 ...
- J2EE相关总结
Java Commons The Java™ Tutorials: http://docs.oracle.com/javase/tutorial/index.html Java Platform, E ...
- location.pathname;outline:medium;undefined不能加引号
1. location.pathname -- 返回URL的域名后的部分.例如 http://www.dreamdu.com/xhtml/ 返回/xhtml/ 2. 判断某个名称为undefined时 ...
- Cmd Markdown 简明语法手册
『Cmd 技术渲染的沙箱页面,点击此处编写自己的文档』 Cmd Markdown 简明语法手册 标签: Cmd-Markdown 1. 斜体和粗体 使用 * 和 ** 表示斜体和粗体. 示例: 这是 ...
- 浅谈AsyncState与AsyncDelegate使用的异同
对于AsyncState来说,其MSDN的解释为:得到BeginInvoke方法的最后一个参数.而对于AsyncDelegate来说,其MSDN的解释为:得到异步调用的委托对象.也就是异步调用的委托源 ...
- is(C# 参考)
检查对象是否与给定类型兼容. 例如,下面的代码可以确定对象是否为 MyObject 类型的一个实例,或者对象是否为从 MyObject 派生的一个类型: if (obj is MyObject ...
- seleniumAccessors
assertErrorOnNext(message) 告诉Selenium在下一个命令执行时期待有错误. 参数:·message–我们所期望的错误信息.如果出现不正确的错误信息,该命令将失败.同断言相 ...
- CentOS中yum安装软件时报错:No package XXX available
yum 安装软件时,报错:No package XXX available. [root@localhost ~]# yum -y install redis Loaded plugins: fast ...
- [BI基础] 一些不得不了解的概念
0.Hadoop hadoop主要是用来对海量数据进行存储和计算的. 它本身是一个分布式系统,核心由分布式文件系统hdfs,和分布式计算框架mapreduce组成,在存储和计算时能够发挥出集群中每台机 ...
- 背景大图隔几秒切换(非轮播,淡入淡出)--变形金刚joy007 项目总结
工作日想了好久,周日回家才想出来的... 图片切换(非轮播,淡入淡出) 1.切换2.停止 <html> <head> <meta content="text/h ...