关于内部类先了解一下它的作用:
1.内部类可以很好的实现隐藏,一般的非内部类,是不允许有 private 与protected权限的,但内部类可以
2.内部类拥有外围类的所有元素的访问权限
3.可是实现多重继承
4.可以避免修改接口而实现同一个类中两种同名方法的调用。(不过一般直接改名就能解决)
内部类真正的设计理由:
java中的内部类和接口加在一起,可以的解决常被C++程序员抱怨java中存在的一个问题 没有多继承。实际上,C++的多继承设计起来很复杂,而java通过内部类加上接口,可以很好的实现多继承的效果。
在《Think in java》中有这样一句话:使用内部类最吸引人的原因是:每个内部类都能独立地继承一个(接口的)实现,所以无论外围类是否已经继承了某个(接口的)实现,对于内部类都没有影响。 在我们程序设计中有时候会存在一些使用接口很难解决的问题,这个时候我们可以利用内部类提供的、可以继承多个具体的或者抽象的类的能力来解决这些程序设计问题。可以这样说,接口只是解决了部分问题,而内部类使得多重继承的解决方案变得更加完整。
内部类基础
在 Java 中,可以将一个类定义在另一个类里面或者一个方法里面,这样的类称为内部类。广泛意义上的内部类一般来说包括这四种:成员内部类、局部内部类、匿名内部类和静态内部类。下面就先来了解一下这四种内部类的用法。
1. 成员内部类:
成员内部类是定义在外部类中的一个类,他可以直接访问外部类中的所有成员变量和成员方法(包括private 成员和静态成员)
package inner;
class Outer{
private int age;
private static String str = "内部类";
public Outer(int age) {
this.age = age;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
class Inner1 {
public void printAge(){
System.out.println(str);
System.out.println(age);
}
}
}
public class demo1 {
public static void main(String[] args) {
Outer outer = new Outer(12);
Outer.Inner1 in = outer.new Inner1();
in.printAge();
}
}
这里有个特殊的地方就是当外部类和内部类中有同名的成员属性和方法时,会发生隐藏现象,即默认情况下访问的是成员内部类的成员。如果要访问外部类的同名成员,需要以下面的形式进行访问:
package inner;
class Outer{
private int age;
private static String str = "外部类";
public Outer(int age) {
this.age = age;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
class Inner1 {
private int age;
public Inner1(int age) {
this.age = age;
}
public void printAge(){
System.out.println("str:"+Outer.this.str);
System.out.println("外部类:"+Outer.this.age);
System.out.println("内部类:"+age);
}
}
}
public class demo1 {
public static void main(String[] args) {
Outer outer = new Outer(12);
/*必须先有外部类的对象才能生成内部类的对象,因为内部类的作用就是为了访问外部类中的成员变量。*/
Outer.Inner1 in = outer.new Inner1(1);
in.printAge();
}
}
局部内部类
有这样一种内部类,它是嵌套在方法的,对于这个类的使用主要是应用与解决比较复杂的问题,想创建一个类来辅助我们的解决方案,到那时又不希望这个类是公共可用的,所以就产生了局部内部类,局部内部类和成员内部类一样被编译,只是它的作用域发生了改变,它只能在该方法和属性中被使用,出了该方法和属性就会失效。
package inner;
class Outer1{
private String str = "外部类中的属性";
public void outer_Method(){
String str2 = "外部类方法中的属性";
//内部类不能被public、private、static修饰;
class Inner{
String str = "内部类中的属性";
public void inner_method(){
System.out.println(str2);
System.out.println(str);
//若有同名时
System.out.println(Outer1.this.str);
}
}
// 只能在外部类的方法中声明实列
Inner inner = new Inner();
inner.inner_method();
}
}
public class Demo2 {
public static void main(String[] args) {
Outer1 outer = new Outer1();
outer.outer_Method();
}
}
- [ 这里有个问题关于外部类方法中的属性是否用finnal]
静态内部类
作用:创建是不需要依赖于外围类的。
静态内部类的作用
package inner;
class Outer3{
public static String str = "静态成员变量";
static class Inner{
public void print(){
//只能访问外部类中的静态属性
System.out.println(str);
}
}
}
public class Demo3 {
public static void main(String[] args) {
//因为内部类被静态化,因此 Out.In 可以当做一个整体看,可以直接 new 出内部类的对象
Outer3.Inner inner = new Outer3.Inner();
inner.print();
}
}
匿名内部类
如果一个内部类在整个操作中只使用一次的话,就可以定义为匿名内部类。匿名内部类也就是没有名字的内部类,这是java为了方便我们编写程序而设计的一个机制,因为有时候有的内部类只需要创建一个它的对象就可以了,以后再不会用到这个类,这时候使用匿名内部类就比较合适。
匿名内部类也就是没有名字的内部类正因为没有名字,所以匿名内部类只能使用一次,它通常用来简化代码编写,
package inner;
interface Inner4{
public void run();
}
class Outer4 {
public void test() {
Inner4 inner4 = new Inner4() {
public void run(){
System.out.println("匿名内部类");
}
}; //记得分号
inner4.run();
}
}
public class Demo4 {
public static void main(String[] args) {
Outer4 outer4 = new Outer4();
outer4.test();
}
}
- 匿名内部类不能定义任何静态成员、方法。
- 匿名内部类中的方法不能是抽象的;
- 匿名内部类必须实现接口或抽象父类的所有抽象方法。
- 匿名内部类访问的外部类成员变量或成员方法必须用static修饰;
- 匿名内部类为局部内部类,所以局部内部类的所有限制同样对匿名内部类生效。