内部类基本概念
定义:在一个类内部除了属性和方法外可以继续嵌套其他的类。
例子:
class A{ //外部类
private String x="woaizuguo";
public void fun(){
Inner a=new Inner(); //实例化内部类
a.print(); //调用内部类方法
}
class Inner{ //内部类
public void print(){
System.out.println(A.this.x);//外部类属性调用
}
}
}
public class Neibulei {
public static void main(String[] args) {
A b=new A(); //实例化外部类
b.fun();
}
}
输出:woaizuguo
内部类破坏了代码的合理结构。但是也具有其优势:轻松访问外部类私有属性
内部类相关说明
1.外部类和内部类之间的私有属性和方法都可以互相访问
例子:外部类访问内部类私有属性
class A{ //外部类
private String x="woaizuguo";
public void fun(){
Inner a=new Inner(); //实例化内部类
a.print(); //调用内部类方法
System.out.println(a.y);//通过外部类实例化内部类对象访问内部类属性
}
class Inner{ //内部类
private String y="weihuzuguotongyi";
public void print(){
System.out.println(A.this.x);//外部类属性调用
}
}
}
public class Neibulei {
public static void main(String[] args) {
A b=new A(); //实例化外部类
b.fun();
}
}
输出结果:
woaizuguo
Weihuzuguotongyi
2.内部类本身也属于一个类,外部类可以产生内部类的实例化对象。此时内部类实例化对象格式如下:
外部类.内部类 内部类对象=new 外部类().new 内部类();
在内部类编译完成之后会形成一个(外部类
内
部
类
.
c
l
a
s
s
)
,
其
中
内部类.class),其中
内部类.class),其中在代码中即为“.”。内部类与外部类之间可以直接进行私有成员访问,在内部类实例化对象前应该保证外部类已经实例化。
class A{ //外部类
private String x="woaizuguo";
class Inner{ //内部类
private String y="weihuzuguotongyi";
public void get(){
System.out.println(this.y);
}
public void print(){
System.out.println(A.this.x);//外部类属性调用
}
}
}
public class Neibulei {
public static void main(String[] args) {
A.Inner b=new A().new Inner(); //实例化外内部类
b.print();
b.get();
}
}
如果此时限制外部类访问内部类,只允许内部类访问外部类,可在内部类前添加private。此时的内部类无法在外部使用。
3.在Java中与之类似的还有抽象类与接口,其二者之中都可以定义内部结构。
例子:内部接口,通过内部类来实现内部接口
interface IMessage{
public void send(IMessageImpl y);
interface IMessageImpl{
public String getMessage();
}
}
class A implements IMessage{
public void send(IMessageImpl y){
System.out.println("发送消息:"+y.getMessage());
}
class B implements IMessageImpl{
public String getMessage(){
return "爱我中国";
}
}
}
public class Neibulei {
public static void main(String[] args) {
IMessage a=new A();
a.send(((A)a).new B());
}
}
4.内部抽象类定义范围较广,可以定义在抽象类中,普通类中,接口内部。
例子:观察内部抽象类
interface IMessage{
public void send();
abstract class MessageImpl{
public abstract String getMessage();
}
}
class A implements IMessage{
public void send(){
MessageImpl a=new B();
System.out.println (a.getMessage());
}
class B extends MessageImpl{
public String getMessage(){
return "爱我中国";
}
}
}
public class N {
public static void main(String[] args) {
IMessage b=new A();
b.send();
}
}
6.如果定义了一个接口,可以在内部利用类实现该接口。利用static不受到实例化对象的控制特性,实现功能。
例子:接口内部进行接口实现
interface IMessage{
public void send();
class MessageImpl implements IMessage{
public void send(){
System.out.println ("ahh,qad");
}
}
public static IMessage get(){
return new MessageImpl();
}
}
public class N {
public static void main(String[] args) {
IMessage b=IMessage.get();
b.send();
}
}
static定义内部类
1、如果在内部类定义上使用了static定义,那么这个类就变成了外部类。static定义的结构是独立于类的结构,那么用static定义的内部类相当于一个独立的程序类。static定义的不管是类还是方法都只能访问static成员,所以static定义的内部类只能访问外部static属性和方法。
例子:定义static内部类
class IMessage{
private static final String AAA="中华小子";
static class MessageImpl {
public void send(){
System.out.println (IMessage.AAA);
}
}
}
public class N {
public static void main(String[] args) {
}
}
这个时候MessageImpl类是一个独立的类,如果此时想要实例化MessageImpl 类对象 ,只需要根据内部类.外部类的结构实例化:外部类.内部类 内部类对象=new 外部类.内部类();
例子:观察static内部类实例化对象
class IMessage{
private static final String AAA="中华小子";
static class MessageImpl {
public void send(){
System.out.println (IMessage.AAA);
}
}
}
public class N {
public static void main(String[] args) {
IMessage.MessageImpl a=new IMessage.MessageImpl();
a.send();
}
}
在开发之中如果发现类名称提供有“.”,则应该认识到这是一个内部类结构。如果直接进行实例化,应该认识到这是应该static定义的内部类。
2、static定义内部接口最常用。
例子:使用static定义内部接口
interface IMessage{ //接口
static interface Messagea { //静态内部接口
public String get();
}
static interface Messageb{ //静态内部接口
public boolean connect();
}
public static void send(Messagea a,Messageb b){ //静态方法
if(b.connect()){
System.out.println(a.get());
}else{
System.out.println("通道异常无法建立连接");
}
}
}
class MessageA implements IMessage.Messagea{ //内部子接口
public String get(){
return "爱我中华";
}
}
class MessageB implements IMessage.Messageb{ //内部子接口
public boolean connect(){
return true;
}
}
public class N {
public static void main(String[] args) {
IMessage.send(new MessageA(),new MessageB());
}
}
使用static定义内部接口是因为这些接口是一组相关操作。有了外部接口之后可以更加明确描述这些接口的主要功能。
方法中定义内部类
内部类可以在任意结构中的定义。
例子:观察方法中定义的内部类
class MessageA {
private String a= "爱我中华";
public void get(){
class A{//内部类
public void print(){
System.out.println(MessageA.this.a);
}
}
new A().print();//方法中直接实例化对象
}
}
public class N {
public static void main(String[] args) {
new MessageA().get();//爱我中华
}
}
此时在方法get()内部提供有类class A的定义,并且该类可以直接访问外部的私有属性和方法中的参数。但是对于参数直接访问开始于jdk1.8。若jdk1.8之前想访问方法中的参数,则参数之前必须追加final。
例子:jdk1.8以前方法中的内部类访问方法中的参数
class MessageA {
private String a= "爱我中华";
public void get(final String x){
final String b="伟大复兴";
class A{//内部类
public void print(){
System.out.println(MessageA.this.a);//爱我中华
System.out.println(x);//和平统一
System.out.println(b);//伟大复兴
}
}
new A().print();//方法中直接实例化对象
}
}
public class N {
public static void main(String[] args) {
new MessageA().get("和平统一");
}
}
匿名内部类
匿名内部类主要用于抽象类和接口的使用。如果有时候某一个接口的实现只是使用一次,则定义类实现过去浪费,此时使用匿名内部类定义完成。
例子:观察基本结构
正常结构
interface Message {
public void send( String x);
}
class A implements Message{
public void send( String x){
System.out.println(x);
}
}
public class N {
public static void main(String[] args) {
new A().send("和平统一");
}
}
匿名内部类
interface Message {
public void send(String x);
}
public class N {
public static void main(String[] args) {
Message a=new Message(){ //匿名内部类
public void send( String x){
System.out.println(x);
}
};
a.send("和平统一");
}
}
有时候为了更加方便体现匿名内部类使用。利用静态方法做一个内部的匿名内部类。
例子:接口中直接定义内部类
interface Message {
public void send(String x);
public static Message get(){
return new Message(){
public void send(String x){
System.out.println(x); //幸福安康
}
};
}
}
public class N {
public static void main(String[] args) {
Message.get().send("幸福安康");
}
}
与内部类相比,匿名内部类只是一个没有名字的、只能使用一次的、具有固定结构的操作。