内部类一
2015-10-24 20:03
162 查看
关于java的内部类,尤其匿名类,会感到无法理解,下文简单实验总结一下。由于内部类涉及很多知识,其中很多没有涉及到。如有表述代码错误,欢迎读者指正!
那为什么使用内部类呢?《thinking in java》第十章中,指出:一般来说,内部类继承自某个类或实现某个接口,内部类的代码操作创建它的外围类的对象,所以可以认为内部类提供了某些进入其外围类的窗口。其最吸引之处,每个内部类都能独立的继承自一个(接口的)实现,所以无论外围类是否已经继承了某个(接口的)实现,对于内部类都没有影响。
内部类和接口可以实现c++中的多继承的作用效果。
简单内部类:
点击(此处)折叠或打开
public class Parcell1 {
private int i = 5;
class Contents{
private int i = 1;
public int value(){ return Parcell1.this.i;}
}
class Destination{
private String label;
private int i = 6;
Destination(String whereTo){
label = whereTo;
}
String readLabel(){ return label;}
public void ship(String dest){
Contents c = new Contents();
System.out.println(value());
Destination d = new Destination(dest);
System.out.println(d.readLabel());
}
public static void main(String[] args){
Parcell1 p = new Parcell1();
p.ship("wang");
}
}
上面Contents,Destination类在Parcell1内部,Parcell1对象通过调用函数ship,创建了两内部类的对象,然后通过调用内部类的函数,打印出私有域的值。上述看以看出这两个内部类就如外部类的成员一样,逻辑结构比较简单,我把这种内部类称之为简单内部类,当然也可称成员内部类,同理它可以被权限修饰词修饰,如果是private,则只能在外部类内部被访问,若是public,则可以在任意地方被访问,若是protected,则只能在包内和其子类访问,和普通的类成员没有区别。
要注意的是,在内部类Contents中,打印的是外围类的私有域值,由于内部类可以引用外围类的成员变量及方法,引用格式:
局部内部类:
顾名思义,这种类定义在方法内或者域内,而且它的作用域也局限于方法和域内,不能被访问权限修饰词所修饰。
点击(此处)折叠或打开
interface pr {
void print1();
}
点击(此处)折叠或打开
public class Parcell2 {
private int i = 5;
public pr ship(String wang){
class Destination implements pr {
private String label;
private int i = 6;
Destination(String whereTo){
label = whereTo;
RetrunLabel();
}
public void print1() {
System.out.println(label);
}
public void RetrunLabel(){
System.out.println(label);
}
}
return new Destination(wang);
}
public static void main(String[] args){
Parcell2 p = new Parcell2();
pr wang = p.ship("wang");
}
}
上面局部类放在返回值是接口对象类型的函数中,该类继承了该接口,该题只是简单的打印出了内部类的私有域,其中可以自定义很多内容,读者感兴趣可以尝试。
静态内部类:
如果我们把内部类看成是外部类的成员,则并不矛盾。静态内部类不能只想外部类的引用,而且在任何非静态内部类中,都不能有静态数据,静态方法或者又一个静态内部类(内部类的嵌套可以不止一层)。不过静态内部类中却可以拥有这一切。
点击(此处)折叠或打开
public class Parcell3 {
private int i = 5;
static class Destination{
private String label;
private static int i = 5;
//private static int j = 6; //error if the class is not static
Destination(String whereTo){
label = whereTo;
}
int readi(){ return i;} //Parcell3.this.i;
error
}
public void ship(String dest){
Destination d = new Destination(dest);
System.out.println(d.readi());
}
public static void main(String[] args){
Parcell3 p = new Parcell3();
p.ship("wang");
}
}
匿名类:
匿名类是不能有名称的类,所以没办法引用他们。必须在创建时,作为new语句的一部分来声明他们。
这就要采用另一种形式 的new语句,如下所示:
new <类或接口> <匿名类的主体>
这种形式的new语句声明一个 新的匿名类,他对一个给定的类进行扩展,或实现一个给定的接口。他还创建那个类的一个新实例,并把他作为语句的结果而返回。要扩展的类和要实现的接口是 new语句的操作数,后跟匿名类的主体。
点击(此处)折叠或打开
public interface prr {
String print1();
String geti();
}
点击(此处)折叠或打开
public class Parcell4 {
private int i = 5;
private String ss;
Parcell4(String ss){
this.ss = ss;
}
public prr ship(String qq){
return new prr(){
public String print1() {
return ss + qq;
}
public String geti(){
return "Lios" + "\n" +i;
}
};
}
public static void main(String[] args){
Parcell4 p = new Parcell4("diy_");
prr c = p.ship("os");
String s = p.ship("os").print1();
System.out.println(s);
System.out.println(c.geti());
}
}
上面我们不知道一个匿名类的名字,而return new prr()这一句很让人寻味,好像在实例化一个prr对象(接口是高级抽象类,当然不能被实例化),但是此时又恰好创建一个类,但是我们无法知道它的名字。
我们把上面的匿名内部类改成一般形式:
点击(此处)折叠或打开
package 第十章内部类;
public interface prr {
String print1(String bb);
String geti();
}
点击(此处)折叠或打开
public class Parcell5 {
private int i = 5;
private String ss;
Parcell5(String ss){
this.ss = ss;
}
class WANG implements prr{
public String print1(String bb) {
return ss + bb;
}
public String geti(){
return "Lios" + "\n" +i;
}
}
public prr ship(){
return new WANG();
}
public static void main(String[] args){
Parcell5 p = new Parcell5("diy_");
prr c = p.ship();
String s = p.ship().print1("os");
System.out.println(s);
System.out.println(c.geti());
}
}
我们发现使用抽象类很简洁,但是要注意几点:
1.匿名内部类是没有访问修饰符的。
2.new 匿名内部类,这个类(接口)首先是要存在的。
3.匿名内部类是没有构造方法。
文章参考:
(点击打开链接,点击打开链接)
那为什么使用内部类呢?《thinking in java》第十章中,指出:一般来说,内部类继承自某个类或实现某个接口,内部类的代码操作创建它的外围类的对象,所以可以认为内部类提供了某些进入其外围类的窗口。其最吸引之处,每个内部类都能独立的继承自一个(接口的)实现,所以无论外围类是否已经继承了某个(接口的)实现,对于内部类都没有影响。
内部类和接口可以实现c++中的多继承的作用效果。
简单内部类:
点击(此处)折叠或打开
public class Parcell1 {
private int i = 5;
class Contents{
private int i = 1;
public int value(){ return Parcell1.this.i;}
}
class Destination{
private String label;
private int i = 6;
Destination(String whereTo){
label = whereTo;
}
String readLabel(){ return label;}
public void ship(String dest){
Contents c = new Contents();
System.out.println(value());
Destination d = new Destination(dest);
System.out.println(d.readLabel());
}
public static void main(String[] args){
Parcell1 p = new Parcell1();
p.ship("wang");
}
}
上面Contents,Destination类在Parcell1内部,Parcell1对象通过调用函数ship,创建了两内部类的对象,然后通过调用内部类的函数,打印出私有域的值。上述看以看出这两个内部类就如外部类的成员一样,逻辑结构比较简单,我把这种内部类称之为简单内部类,当然也可称成员内部类,同理它可以被权限修饰词修饰,如果是private,则只能在外部类内部被访问,若是public,则可以在任意地方被访问,若是protected,则只能在包内和其子类访问,和普通的类成员没有区别。
要注意的是,在内部类Contents中,打印的是外围类的私有域值,由于内部类可以引用外围类的成员变量及方法,引用格式:
局部内部类:
顾名思义,这种类定义在方法内或者域内,而且它的作用域也局限于方法和域内,不能被访问权限修饰词所修饰。
点击(此处)折叠或打开
interface pr {
void print1();
}
点击(此处)折叠或打开
public class Parcell2 {
private int i = 5;
public pr ship(String wang){
class Destination implements pr {
private String label;
private int i = 6;
Destination(String whereTo){
label = whereTo;
RetrunLabel();
}
public void print1() {
System.out.println(label);
}
public void RetrunLabel(){
System.out.println(label);
}
}
return new Destination(wang);
}
public static void main(String[] args){
Parcell2 p = new Parcell2();
pr wang = p.ship("wang");
}
}
上面局部类放在返回值是接口对象类型的函数中,该类继承了该接口,该题只是简单的打印出了内部类的私有域,其中可以自定义很多内容,读者感兴趣可以尝试。
静态内部类:
如果我们把内部类看成是外部类的成员,则并不矛盾。静态内部类不能只想外部类的引用,而且在任何非静态内部类中,都不能有静态数据,静态方法或者又一个静态内部类(内部类的嵌套可以不止一层)。不过静态内部类中却可以拥有这一切。
点击(此处)折叠或打开
public class Parcell3 {
private int i = 5;
static class Destination{
private String label;
private static int i = 5;
//private static int j = 6; //error if the class is not static
Destination(String whereTo){
label = whereTo;
}
int readi(){ return i;} //Parcell3.this.i;
error
}
public void ship(String dest){
Destination d = new Destination(dest);
System.out.println(d.readi());
}
public static void main(String[] args){
Parcell3 p = new Parcell3();
p.ship("wang");
}
}
匿名类:
匿名类是不能有名称的类,所以没办法引用他们。必须在创建时,作为new语句的一部分来声明他们。
这就要采用另一种形式 的new语句,如下所示:
new <类或接口> <匿名类的主体>
这种形式的new语句声明一个 新的匿名类,他对一个给定的类进行扩展,或实现一个给定的接口。他还创建那个类的一个新实例,并把他作为语句的结果而返回。要扩展的类和要实现的接口是 new语句的操作数,后跟匿名类的主体。
点击(此处)折叠或打开
public interface prr {
String print1();
String geti();
}
点击(此处)折叠或打开
public class Parcell4 {
private int i = 5;
private String ss;
Parcell4(String ss){
this.ss = ss;
}
public prr ship(String qq){
return new prr(){
public String print1() {
return ss + qq;
}
public String geti(){
return "Lios" + "\n" +i;
}
};
}
public static void main(String[] args){
Parcell4 p = new Parcell4("diy_");
prr c = p.ship("os");
String s = p.ship("os").print1();
System.out.println(s);
System.out.println(c.geti());
}
}
上面我们不知道一个匿名类的名字,而return new prr()这一句很让人寻味,好像在实例化一个prr对象(接口是高级抽象类,当然不能被实例化),但是此时又恰好创建一个类,但是我们无法知道它的名字。
我们把上面的匿名内部类改成一般形式:
点击(此处)折叠或打开
package 第十章内部类;
public interface prr {
String print1(String bb);
String geti();
}
点击(此处)折叠或打开
public class Parcell5 {
private int i = 5;
private String ss;
Parcell5(String ss){
this.ss = ss;
}
class WANG implements prr{
public String print1(String bb) {
return ss + bb;
}
public String geti(){
return "Lios" + "\n" +i;
}
}
public prr ship(){
return new WANG();
}
public static void main(String[] args){
Parcell5 p = new Parcell5("diy_");
prr c = p.ship();
String s = p.ship().print1("os");
System.out.println(s);
System.out.println(c.geti());
}
}
我们发现使用抽象类很简洁,但是要注意几点:
1.匿名内部类是没有访问修饰符的。
2.new 匿名内部类,这个类(接口)首先是要存在的。
3.匿名内部类是没有构造方法。
文章参考:
(点击打开链接,点击打开链接)
相关文章推荐
- (NO.00001)iOS游戏SpeedBoy Lite成形记(十八)
- (NO.00001)iOS游戏SpeedBoy Lite成形记(十八)
- xml解析 iOS
- 数据仓库的特点总结
- IDF 牛刀小试-ASCII码而已
- String动手动脑
- 13 Large sum - Project Euler
- 求100以内的素数2015 10 24
- zoj3905 Cake (简单dp)
- 杭电1163--9余项定理的例子
- codeforces 7c line(扩展欧几里得)
- 并发队列之:BlockingQueue和ConcurrentLinkedQueue
- scala学习笔记(4):占位符
- C# 多线程学习系列一:认识多线程
- 动手动脑及作业
- UITextField-->详解
- iOS “智慧气象”APP中用到的第三方框架汇总
- 第四十天:提示符 -- PS1
- Partition函数
- iOS开发9-iOS操作SQLite数据库增删改查