1、前沿
在Android开发中时常能够遇到内部类等,但总是不敢大胆的使用,本人想通过该篇技术博客来对这些类的特点和注意点做下记录,以此来保证开发出来的代码性能优秀,结构清晰。
2、分类别展示实例
2.1 内部类定义
可以将一个类的定义放在另一个类的定义内部,就是内部类。
2.2 互相访问
内部类能访问外部类对象的所有成员,即内部类自动拥有对其外围类的所有成员的访问权。
需要注意的是: 1. 普通的内部类对象隐式地保存了一个引用,该引用指向创建它的外围类的对象。
2. 普通内部类内部不能包含 staic数据和staic字段,更不能包含静态内部类,当然了可以访问
/**
* Created by zxl on 2018/7/26.
* description: 内部类特点1
* 内部类和外部类可以互相访问,包括私有变量
*/
public class FirstInnerClass {
private String[] arrays = new String[10];
public FirstInnerClass(){
for (int i=0;i<10;i++){
arrays[i] = "数据"+i+" ";
}
}
public InnerClass createInner(){
InnerClass innerClass = new InnerClass();
// 外部类也可以访问内部类的私有变量
System.out.println(innerClass.num);
return innerClass;
}
class InnerClass{
private int num = 20;
public void method(){
// 可以发现,可以访问到外部类的私有变量
for (String array : arrays) {
System.out.print(array);
}
}
}
}
public class Client {
public static void main(String[] args){
FirstInnerClass.InnerClass innerClass = new FirstInnerClass().createInner();
innerClass.method();
//20
//数据0 数据1 数据2 数据3 数据4 数据5 数据6 数据7 数据8 数据9
}
}
指示,对于非静态内部类而言其他对象创建内部类的对象,不得不采用 .new( )语法。记住必须得使用外部类的对象来创建其内部类对象。
FirstInnerClass firstInnerClass = new FirstInnerClass();
FirstInnerClass.InnerClass innerClass1 = firstInnerClass.new InnerClass();
当成员内部类拥有和外部类同名的成员变量或者方法时,会发生隐藏现象,即默认情况下访问的是成员内部类的成员。如果要访问外部类的同名成员,需要以下面的形式进行访问:
外部类.
this
.成员变量
外部类.
this
.成员方法
2.3 内部类和向上转型
首先看下常规的向上转型吧,这样拓展是没问题的,之后可以增加接口方法来拓展功能。
public interface ClickListener {
void onClick();
}
public class Button implements ClickListener{
@Override
public void onClick() {
System.out.println(getClass().getName()+" onClick");
}
}
public class Client {
public static void main(String[] args){
ClickListener clickListener = new Button();
clickListener.onClick();
// normal.Button onClick
}
}
外围无法访问私有的内部类的对象,无法获得引用的,确已是受限制的。private内部类可以组织依赖于类型的编码。除了开发程序的,客户端是无法通过拓展接口来变更。
public class SndInnerClass {
private class MyTextView implements ClickListener{
@Override
public void onClick() {
System.out.println(getClass().getName()+" onClick");
}
}
public MyTextView getConnect(){
return new MyTextView();
}
}
public class Client {
public static void main(String[] args){
ClickListener clickListener = new SndInnerClass().getConnect();
clickListener.onClick();
// normal.SndInnerClass$MyTextView onClick
// !由于内部类为private类型,故而不可通过 外部类.new 内部类 的方式来创建对象了
// SndInnerClass.MyTextView 本身就无法获得,根本无法访问成员,也仅仅可通过外部类去操作返回
}
}
2.4 内部类延展
2.4.1局部内部类
类的定义在方法的作用域内,即为局部内部类。
/**
* Created by zxl on 2018/7/26.
* 注意 对于如下的局部内部类,该类是属于getText()方法的,不能通过该方法以外的其他方法去获得该对象
* 留意其作用域
*/
public class PartInnerClass {
public ClickListener getText(){
class MyEditText implements ClickListener{
@Override
public void onClick() {
System.out.println(getClass().getName()+" onClick");
}
}
return new MyEditText();
}
}
public class Client {
public static void main(String[] args){
ClickListener text = new PartInnerClass().getText();
text.onClick();
// normal.PartInnerClass$1MyEditText onClick
}
}
2.4.2 匿名内部类
/**
* Created by zxl on 2018/7/26.
* 匿名内部类 实则是在方法里返回一个对象,该对象是继承了一个特定的类
*/
public class AnnoyInnerClass {
/* 该类(ClickListener) 或者接口是存在的*/
public ClickListener connects(){
return new ClickListener(){
@Override
public void onClick() {
System.out.println(getClass().getName()+" "+" 哈哈");
}
};
}
}
public class Client {
public static void main(String[] args){
ClickListener connects = new AnnoyInnerClass().connects();
connects.onClick();
// normal.AnnoyInnerClass$1 哈哈
}
}
传参继承也是OK的
public class AnnoyInnerClass2 {
public ClickListener showName(int x){
return new MyAnnoyListener(x);
}
}
class MyAnnoyListener implements ClickListener{
private int value;
public MyAnnoyListener(int value){
this.value = value;
}
@Override
public void onClick() {
System.out.println(getClass().getName()+" 点击次数:"+value);
}
}
2.4.3 嵌套类 -- 静态内部类
特点:1. 创建静态内部类不需要外围内的对象。也就是说不会持有外围类的引用
2.不能从静态内部类的对象中访问非静态的外围类对象
3. 静态内部不可使用this 引用
public class StaticInnerClass {
private static int num = 30;
public static class MyInnerClass{
private static int i = 20;
public void method(){
System.out.println("外部类 num = "+num);
}
class InnerTo{
public void showName(){
System.out.println("外部类的外部类 num = "+num);
System.out.println("外部类的 i = "+i);
}
}
}
}
public class Client {
public static void main(String[] args){
StaticInnerClass.MyInnerClass myInnerClass = new StaticInnerClass.MyInnerClass();
myInnerClass.method();
StaticInnerClass.MyInnerClass.InnerTo innerTo = myInnerClass.new InnerTo();
innerTo.showName();
}
}
3、总结
最吸引人的原因,每个内部类都能独立的继承自一个实现。 也就是说弥补了类的单一继承。
讲的很好的链接: Java内部类详解