内部接口和内部抽象类的一些使用
一、什么是内部类
1、类里面定义的类就叫做内部类。
class Outer{ //外部类
private String str ="I love myself";//私有成员属性
public void fun(){ //普通方法
Inner in=new Inner(); //实例化内部类对象,调用内部类方法
in.print();
}
class Inner{ //属于Outer的内部类的Inne类
public void print(){
System.out.println(Outer.this.str); //在Inner类中打印Outer类的属性
}
}
}public class Demo{
public static void main(String[] args) {
Outer out=new Outer();
out.fun();
}
}
结果
C:\Users\Desktop\code\内部类>java Demo
I love myself
2、不使用内部调用私有属性,
class Outer{
private String str ="I love myself";//私有成员属性
//想让外部访问私有属性,得有geeter方法
public String getStr(){
return this.str;
}
public void fun(){ //普通方法
//将Outer类对象传递到Inner类中
Inner in=new Inner(this);
in.print();
}
}
class Inner{
//想使用Outer类的属性,在Inner对象实例化的时候需要Outer类的引用
private Outer out;
public Inner(Outer out){//通过构造方法获取Outer类对象
this.out=out;
}
public void print(){
System.out.println(this.out.getStr()); //通过out对象获取Outer类的属性
}
}
public class Demo2{
public static void main(String[] args) {
Outer out=new Outer();
out.fun();
}
}
结果
C:\Users\Desktop\code\内部类>java Demo2
I love myself
结论:内部类的优势:可以轻松使用外部类的私有属性
3、内部类编译完成后会自动形成一个”内部类名$内部类名.class“文件,这样内部类和外部类之间可以直接进行私有成员的访问。一定要保证外部类对象已经实现实例化。
4、如果内部类只允许外部类使用,就可以使用private进行私有定义
代码
class Outer{ //外部类
private String str ="I love myself";//私有成员属性
private class Inner{
public void print(){
System.out.print(Outer.this.str);
}
}
}
public class Demo3{
public static void main(String[] args) {
Outer.Inner in =new Outer().new Inner();
in.print();
}
}
结果
C:\Users\Desktop\code\内部类>javac -encoding UTF-8 Demo3.java
Demo3.java:11: 错误: Outer.Inner 在 Outer 中是 private 访问控制
Outer.Inner in =new Outer().new Inner();
^
Demo3.java:11: 错误: Outer.Inner 在 Outer 中是 private 访问控制
Outer.Inner in =new Outer().new Inner();
因为内部类被定义成private私有化,不能在外部使用。只能通过外部类去调用
5、抽象类和接口都可以定义内部接口
调用内部类的格式:
外部类.内部类 内部类对象 =new 外部类() .new内部类();
static定义的内部类的调用格式:
外部类.内部类 内部类对象 =new 外部类 .内部类();
二、内部接口
代码:
interface IChannel{//定义接口
public void send(IMessage msg);//发送消息
//接口只有一个方法
interface IMessage{
//内部接口
public String getContent();//获取消息内容
}
}
class ChannelTmpl implements IChannel{//实现IChannel接口的类
public void send(IMessage msg){//实现IChannel接口的方法
System.out.println("发送消息"+msg.getContent());
}
class MessageImpl implements IMessage{//实现IMessage的类
public String getContent(){//实现IMessage接口的方法
return "www .mldn.cn";
}
}
}
public class interfaceText01{
public static void main(String[] args){
IChannel c1=new ChannelTmpl();//实例化一个IChannel对象
c1.send(((ChannelTmpl) c1).new MessageImpl());
}
}
结果:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-SEVHdypo-1625458661757)(C:\Users\杨怡然\Desktop\图片\27.jpg)]
代码总结:
2、内部抽象类
代码
//内部抽象类
interface IChannel{//定义接口
public void send();//发送消息
//接口只有一个方法
abstract class AbstractMessage{//内部抽象类
public abstract String getContent();
}
}
class ChannelTmpl implements IChannel{//实现IChannel接口的类
public void send(){//实现IChannel接口的方法
AbstractMessage msg=new MessageImpl();
System.out.println("发送消息: "+msg.getContent());
}
class MessageImpl extends AbstractMessage{
//实现抽象类,继承抽象类
public String getContent(){
return "every";
}
}
}
public class interfaceText02{
public static void main(String[] args){
IChannel c1=new ChannelTmpl();//实例化一个IChannel对象
c1.send();
}
}
结果:
every
3、static定义
1、 static定义的内部类的调用格式:
外部类.内部类 内部类对象 =new 外部类 .内部类();
2、如果用static定义内部类,这个类就变成了外部类, static定义的不管是方法还是类只能够访问static成员。所以static定义的内部类只能
class Outer{//外部类
private static final String MSG="Happy";
static class Inner{//static定义的内部类,是一个独立类
//如果想要实例化INner对象。需要根据”外部类‘的结构
public void print(){/*定义的print方法*/
System.out.print(Outer.MSG);
}
}
}
public class staticText01{
public static void main(String[] args) {
Outer .Inner in=new Outer.Inner();
in.print();
}
}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ziawrSoK-1625458661759)(C:\Users\杨怡然\Desktop\图片\29.jpg)]
如果类名称提供有“.”,首先想到这是一个内部类的结构,立刻认识到这是一个static定义的内部类,static定义类情况不常用,定义接口的情况很常用
2、static定义的接口
//static定义的接口
interface IMessageWarp{//消息包装
static interface IMessage{//消息内容
public String getContent();
}
static interface IChannel{
public boolean connect();//消息的发送通道
}
public static void send(IMessage msg, IChannel channel){
//消息发送
if (channel.connect()) {
System.out.println(msg.getContent());
}
else{
System.out.println("消息通道无法建立,消息发送失败");
}
}
}
class DefaultMessage implements IMessageWarp.IMessage{
public String getContent(){return "happy";}
}
class NetChannel implements IMessageWarp.IChannel{
public boolean connect(){
return true;
}
}
public class staticText02{
public static void main(String[] args) {
IMessageWarp.send(new DefaultMessage(),new NetChannel() );
}
}
//代码理解:
//在接口IMessageWarp里定义了两个接口IMessage和ICannel以及一个send方法都是用static定义的
结果:
happy
使用static定义的内部接口主要是因为这些操作是属于一组相关的定义,有了外部接口之后可以更加明确的描述出这些接口的主要目的和主要内容
4、匿名内部类
是一种简化的内部类的处理形式,主要是在抽象类和接口的子类上使用,就是没有名字的类
代码:
//匿名类
interface IMessage{
public void send(String str);
}
/*
class MessageImpl implements IMessage{
public void send(String str){
System.out.print(str);
}
}
多余
*/
public class JavaDemo1{
public static void main(String[] args) {
IMessage msg=new IMessage(){//匿名内部类
public void send(String str){
System.out.print(str);
}
};
msg.send("Happy every day");
}
}
结果: 打印出Happy every day
匿名类只能使用一次
5、方法内部定义内部类
//方法中定义内部类
class Outer{
private String msg="mldn";
public void fun(long time){
class Inner{
public void print(){
System.out.println(Outer.this.msg);
System.out.println(time);
}
}
new Inner().print();//方法中直接实例化内部类对象
}
}
public class Demo4{
public static void main(String[] args) {
new Outer().fun(2154545454L);
}
}
需要注意,数字L代表长整型,不能带入小数型数据。
不然会
Demo4.java:16: 错误: 需要')' new Outer().fun(0.2154545454L); ^Demo4.java:16: 错误: 需要';' new Outer().fun(0.2154545454L); ^2 个错
在JDK1.8以前定义必须加final