成为一名合格的工程师需要一年到三年,现在遇到困难的,觉得不会的不要慌,学习是积累的,有一定步骤的。
内部类
内部类的定义
将一个类定义在另一个给类里面或者方法里面,这样的类就被称为内部类。
内部类可以分为四种:成员内部类、局部内部类、匿名内部类、静态内部类,下面我们逐一介绍这四种内部类。
一.成员内部类
他定义在另一个类中。一般定义格式如下
Inner类定义在Outer类的内部,相当于Outer类的成员变量的位置
class C{
class D{
}
}
因为类C相对与类D在外面,我们且称类C为外部类。
1.成员内部类内部不允许存在任何static变量或方法(可以用public static final来定义常量),但是可以访问外部类的实例变量、静态变量、实例方法、静态方法。
(静态变量和静态方法都不能这么申明)
2.成员内部类可以无条件访问外部类的属性和方法,但是外部类想要访问内部类属性或方法时,必须要创建一个内部类对象,然后通过该对象访问内部类的属性或方法
3.成员内部类无条件访问外部类的属性和方法(Inner类可以使用任意访问修饰符,如:public、private、protected等。)
class C{
private String name = "外部类";
public void run(){
System.out.println("外部类奔跑");
}
class D{
public void say(){
System.out.println(name);
run();
}
}
}
外部类访问内部类属性和方法
class C{
private String name = "外部类";
public void run(){
System.out.println("外部类奔跑");
}
/*使用内部类的属性和方法*/
public void eat(){
D d = new D();
System.out.println(d.value);
d.say();
}
class D{
private String value = "DDD";
public void say(){
System.out.println(name);
run();
}
}
}
外部类属性或方法隐藏
如果外部类和内部类具有相同的成员变量或方法,内部类可以直接访问内部类的成员变量或方法,但如果内部类访问外部类的成员变量或者方法时,需要使用this关键字
外部类类名.this.属性/方法。
class C{
private String name = "外部类";
public void run(){
System.out.println("外部类奔跑");
}
/*使用内部类的属性和方法*/
public void eat(){
D d = new D();
System.out.println(d.value);
d.say();
}
class D{
private String value = "DDD";
private String name = "内部类";
public void say(){
System.out.println(C.this.name);
System.out.println(name);
run();
}
}
}
创建内部类对象
显然成员内部类是寄生于外部类,创建内部类对象就必须先创造外部类对象。
在其他类中,是看不见一个类的内部类的。只能通过先创建外部类对象:Outer o = new outer();再 创建内部类:Inner i = o.new Inner()。
在自己本外部类中:1.静态方法内也需要通过上述创建内部类
2.实例方法内可以按普通类创建对象
public class Test10 {
public static void main(String[] args) {
/*方式1创建成员内部类对象*/
C c = new C();
C.D d = c.new D();
/*方式2创建成员内部类对象*/
C.D d1 = c.getClassD();
}
}
class C{
private String name = "外部类";
public void run(){
System.out.println("外部类奔跑");
}
/*创建一个返回D对象的方法*/
public D getClassD(){
return new D();
}
/*使用内部类的属性和方法*/
public void eat(){
D d = new D();
System.out.println(d.value);
d.say();
}
class D{
private String value = "DDD";
private String name = "内部类";
public void say(){
System.out.println(C.this.name);
System.out.println(name);
run();
}
}
}
二.静态内部类
静态内部类和成员内部类相比多了一个static修饰符。它与类的静态成员变量一般,是不依赖于外部类的。
1.静态内部类创建对象不需要依赖外部类对象可以直接创建。(但是需要外部类来定位)
在自己本外部类中:无论是静态方法还是实例方法,都可以直接创建。
在其他的类中:使用内部类的时候仍然使用外部类,定位内部类。见Test方法。
2.静态内部类不可以使用任何外部类的非static属性,也不能访问非static方法(非static方法可以通过创建外部类对象来访问),但可以存在自己的成员变量、实例方法。
class Outer {
public String name = "test";
private static int age =20;
static class Inner{
private String name;
public void fun()
{
System.out.println(name);
System.out.println(age);
}
}
}
public class Test{
public static void main(String [] args)
{
Outer.Inner in = new Outer.Inner();
}
}
三.方法内部类
方法内部类顾名思义就是定义在方法里的类
1.方法内部类不允许使用访问权限修饰符(public、private、protected)均不允许。内部类也不能使用 static 修饰符(方法里面只有局部变量)。
class Outer{
private int num =5;
public void dispaly(final int temp)
{
//方法内部类即嵌套在方法里面
public class Inner{
}
}
}
public class Test{
public static void main(String[] args)
{}
}
2. 方法内部类对外部完全隐藏,除了创建这个类的方法可以访问它以外,其他地方均不能访问 (换句话说其他方法或者类都不知道有这个类的存在)方法内部类对外部完全隐藏,除了创建这个类的方法可以访问它,其他地方均不能访问。
3. 方法内部类如果想要使用方法形参,该形参必须使用final声明(JDK8形参变为隐式final声明)
class Outer{
private int num =5;
//普通方法
public void dispaly(int temp)
{
//方法内部类即嵌套在方法里面
class Inner{
public void fun()
{
System.out.println(num);
temp++;
System.out.println(temp);
}
}
//方法内部类在方法里面创建
new Inner().fun();
}
}
public class Test{
public static void main(String[] args)
{
Outer out = new Outer();
out.dispaly(2);
}
}
四.匿名内部类
匿名内部类就是一个没有名字的方法内部类,因此特点和方法与方法内部类完全一致,除此之外,还有自己的特点:
1.匿名内部类必须继承一个抽象类或者实现一个接口。
2.匿名内部类没有类名,因此没有构造方法。
匿名内部类没有构造方法。也是唯一没有构造方法的内部类。匿名内部类和局部内部类只能访问外部类的final变量。
//匿名内部类
//声明一个接口
interface MyInterface {
//接口中方法没有方法体
void test();
}
class Outer{
private int num = 5;
public void dispaly(int temp)
{
//匿名内部类,匿名的实现了MyInterface接口
//隐藏的class声明
new MyInterface()
{
public void test()
{
System.out.println("匿名实现MyInterface接口");
System.out.println(temp);
}
}.test();
}
}
public class Test{
public static void main(String[] args)
{
Outer out = new Outer();
out.dispaly(3);
}
}
public class Test13 {
public static void main(String[] args) {
driveCar(new Car(){
@Override
public void drive() {
System.out.println("驾驶着BMW汽车");
}
});
}
public static void driveCar(Car car){
car.drive();
}
}
interface Car {
void drive();
}
五. 内部类与外部类的关系
对于非静态的内部类,内部类的创建依赖外部类的实例对象,在没有外部类实例之前是无法创建内部类的。
内部类可以直接访问外部类的元素(包括私有域)—外部类在内部类之前创建,创建内部类时会将外部类的对象传入
class Outer{
//成员变量 与对象有关
private String msg;
private int age;
//--------------------------
class Inner{
public void dispaly()
{
//此处有一个隐藏的Outer.this
msg = "test";
age = 20;
System.out.println(msg);
System.out.println(age);
}
}
//--------------------------
public void test()
{
Inner in = new Inner();
in.dispaly();
}
}
public class Test{
public static void main(String[] args)
{
Outer out = new Outer();
out.test();
}
}
外部类可以通过内部类的引用间接访问内部类元素 – -要想访问内部类属性,必须先创建内部类对象。但是其实不光外部类,其他的类也可以通过此方法访问到内部类属性(内部类是一个相对独立的个体,与外部类没有关系)。
class Outer{
public void dispaly()
{
//外部类通过创建内部类的对象间接访问内部类元素
Inner in = new Inner();
in.dispaly();
}
class Inner{
public void dispaly()
{
System.out.println("内部类");
}
}
}
public class Test1{
public static void main(String[] args)
{
Outer out = new Outer();
out.dispaly();
}
}
六.成员内部类和静态内部类
1.成员内部类可以访问外部类的所有属性和方法。成员内部类不能存在任何static修饰的属性或者方法。
2.静态内部类不能访问外部类非static修饰的属性和方法,但是可以通过创建外部类对象的方式来访问外部类实例方法(这种方法和其他类来创建对象访问外部类没有差别)。静态内部类里面可以存在自己的成员变量、实例方法。