您的位置:首页 > 编程语言 > Java开发

【Java学习笔记】28:再谈四种内部类

2017-08-09 20:13 309 查看
内部类又叫嵌套类,是在类的体内再定义的类。

[1].成员内部类

也叫属性内部类。

它可以当成外部类的成员来看待,所以可以直接访问外部类的所有成员(属性和方法),即使这成员时私有的或者静态的。

外部类要访问内部类的成员时,则需要实例化内部类的对象。可以知道成员内部类不能含有static的变量的方法,但是可以有static常量。

package day28;

public class Test {

public static void main(String[] args) {
Outer outer=new Outer();//先创建一个外部类对象
Outer.Inner inner=outer.getInner();//用外部类对象自写的getInner()方法
outer.b=100;
outer.m2();
inner.a2=100;
inner.x2();
}
}

//外部类
class Outer{
private int a;
public int b;
static int c;

private void m1(){
}
//外部类中如要访问成员内部类的成员,需对内部类实例化
public void m2(){
Outer.Inner inner=new Outer.Inner();
inner.a1=1;
inner.a2=2;
inner.x1();
inner.x2();
}
static void m3(){
}

//常定义这种方法来使外部类访问内部类,这样外部类内部类就都有了
public Inner getInner(){
return new Inner();
}

//成员内部类
class Inner{
private int a1;
public int a2;
static final int a3=1;//可以有这样静态的常量,但是不可以有变量
//成员内部类可以访问外部类的任何成员
private void x1(){
a=1;
b=2;
c=3;
m1();
m2();
m3();
}
public void x2(){
}
}
}


看一下编译后生成的class文件:



[2].静态内部类(常用)

我们知道静态成员不需要实例化,可以通过类名称直接访问。

静态内部类也很类似,不需要实例化外部类就可以访问静态内部类,而且它里面的成员是允许有static关键字的。

静态内部类中的方法常常设置成public方便被调用。

package day28;

public class Test {

public static void main(String[] args) {
Outer.Inner.a=100;//直接访问属性
Outer.Inner.m2();//直接调用方法

//例子测试
int[] a={2,8,19,-7,5,9,16,-3,6,1,0,16};
MaxMin.Pair pair=MaxMin.Pair.getMinMax(a);
System.out.println(pair.max);
System.out.println(pair.min);
}
}

//外部类
class Outer{
static int i;
static void m1(){
}

//静态内部类
static class Inner{
//可以有静态变量和方法
static int a;
static void m2(){
}
}
}

//例子
class MaxMin{

//静态内部类
static class Pair{
static int min,max;
//获取数组中最大最小值
static Pair getMinMax(int[] a){
min=a[0];
max=a[0];
for(int x:a)
{
if(x<min)
min=x;
if(x>max)
max=x;
}
return new Pair(min,max);
}

//生成的两种构造方法
public Pair() {
super();
}

public Pair(int min, int max) {
super();
this.min = min;
this.max = max;
}

//生成的get和set方法
public int getMin() {
return min;
}

public void setMin(int min) {
this.min = min;
}

public int getMax() {
return max;
}

public void setMax(int max) {
this.max = max;
}
}
}


运行结果:

19

-7

[3].局部内部类

就像定义一个局部变量一样,在某个代码块中也可以定义一个类,即是局部内部类。

但它很少见,所以只学习一下语法格式。

package day28;

public class Test {

public static void main(String[] args) {
Outer outer=new Outer();
outer.m1();
}
}

//外部类
class Outer{
int a=1;
int b=2;
public void m1(){
if(a<b)
{
//局部内部类(只在这个代码块中生效)
class Inner{
private int x;
public Inner(int x){
this.x=x;
}
public void printA(){
System.out.println(x);
}
}
Inner inner=new Inner(a);
inner.printA();
}
else
{
System.out.println(b);
}
}
}


运行结果:

1

看一下它的class文件:



[4].匿名内部类(常用)

有时没必要把所有的接口和抽象类都实现一遍,就可以考虑用到匿名内部类。

比如下面这种方式,是常规的类实现接口以完成方法的方式。

package day28;

public class Test {

public static void main(String[] args) {
Computer pc=new Computer();
pc.read();
pc.write();
}
}

//一个接口
interface USB{
public void write();
public void read();
}

//类要实现这个接口
class Computer implements USB{

@Override
public void write() {
System.out.println("writing...");

}

@Override
public void read() {
System.out.println("reading...");
}
}


如果接口太多了而类不是必要,这样做就有些麻烦了,那么可以使用匿名内部类。

package day28;

public class Test {

public static void main(String[] args) {
//接口不能实例化,这里是一个匿名内部类实现了接口的方法并创建了实例
USB usb=new USB(){
public void read(){
System.out.println("reading...");
}
public void write(){
System.out.println("writing...");
}
};
usb.read();
usb.write();
}
}

//一个接口
interface USB{
public void write();
public void read();
}


运行结果:

reading…

writing…

对于抽象类,也可以用匿名内部类去解决类似的问题。

首先是常规的类去继承抽象类以实现其抽象方法的方式如下。

package day28;

public class Test {

public static void main(String[] args) {
Dogs dog=new Dogs();
dog.eat();
dog.sleep();
}
}

//一个抽象类
abstract class Animal{
abstract void eat();
abstract void sleep();
}

//一个类去继承抽象类
class Dogs extends Animal{
public void eat(){
System.out.println("dog eating...");
}
public void sleep(){
System.out.println("dog sleeping...");
}
}


使用匿名内部类,可以像下面这样做。

package day28;

public class Test {

public static void main(String[] args) {
Animal a=new Animal(){
public void eat(){
System.out.println("dog eating...");
}
public void sleep(){
System.out.println("dog sleeping...");
}
};
a.eat();
a.sleep();
}
}

//一个抽象类
abstract class Animal{
abstract void eat();
abstract void sleep();
}


运行结果:

dog eating…

dog sleeping…

看一下生成的class文件:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: