---------------------- ASP.Net+Android+IOS开发.Net培训、期待与您交流! ----------------------

黑马程序员-------------(二)面向对象

目录

一 面向对象概述

    1.面向对象与面向过程的关系

    2.理解面向对象

二 面向对象的特征(一)封装 Encapsulation

    1.private关键字

    2.构造函数

    3.this关键字和super关键字

    4.static关键字

    5.单例设计模式

    6.对象的建立在内存中的体现

三 面向对象的特征(二)继承Inheritance

    1.继承的特点

    2.继承中成员的特点

    3.final关键字

    4.抽象类

    5.模板方法设计模式

    6.接口

四 面向对象的特征(三)多态Polymorphism

    1.概述

    2.多态中成员的特点

    3.转型

    4.instanceof关键字

    5.内部类

注:本章重点内容:static关键字,对象的建立在内存中的体现,单例设计模式,函数覆盖(Override),模板方法设计模式,转型,匿名内部类。
对于重点内容,根据知识的重要程度用◆◆◆、◆◆◆◆、◆◆◆◆◆进行了标注。

####################################################################################
一 面向对象概述
####################################################################################

1.面向对象与面向过程的关系
面向对象和面向过程都是一种思想,面向对象是相对面向过程而言,面向对象是基于面向过程的。面向过程强调的是功能行为;面向对象是将功能
封装进对象,强调具备了功能的对象。

2.理解面向对象
面向对象是一种思想,它能让复杂的问题简单化,能让我们的角色从执行者转换成指挥者,谁拥有数据,谁就对外提供操作这些数据的方法。
举例
(1)人关门。这里有两个对象人和门,一个关门的方法。这个方法应该被定义在门这个对象中,因为关门是一系列动作,如门轴的转动,锁舌的弹出等,而这一系列的数据门最清楚,门拥有这些数据,所以应该是门对外提供如何关的方法,人只是调用门的这个方法。
(2)人在黑板上画圆。这里有三个对象人,黑板和圆,一个画圆的方法。这个方法应该被定义在圆这个对象中,因为画圆需要用到圆心和半径等,而这些数据是圆内部的数据,只有圆本身最清楚。所以应该是圆对外提供操作这些数据的方法。
(3)列车司机紧急刹车。这里有两个对象列车和司机,一个紧急刹车的方法。这个方法应该被定义在列车这个对象中。因为刹车需要发动机熄火,离合器离合,抱闸系统把轮子抱死等一系列的动作。而这些列车最清楚,司机只是给了一个外力,相当于调用了列车的这个方法。
(4)售货员统计小票的金额。这里有两个对象售票员和小票,一个统计金额的方法。这个方法应该被定义在小票这个对象中,因为统计小票需要知道商品买了几件以及商品的价格是多少,这些数据都在小票上,小票最清楚,小票拥有这些数据,所以应该是小票对外提供操作这些数据的方法。
(5)我报名参加黑马程序员训练营。这里有两个对象我和黑马,一个报名的方法。这个方法应该被定义在黑马这个对象中,因为报名需要填表格,做测试,笔试和面试等,而这些流程是黑马制定的,她对这些流程最清楚,所以应该是黑马对外提供报名的方法,我调用黑马的这个方法。

####################################################################################
二 面向对象的特征(一) 封装 Encapsulation
####################################################################################

封装:是指隐藏对象的属性和实现细节,仅对外提供公共访问方式。它的好处是可以将变化隔离;便于使用;提高重用性;提高安全性;
封装原则:将不需要对外提供的内容都隐藏起来。把属性都隐藏,提供公共方法对其访问。

1.private 关键字

private:私有,权限修饰符,成员修饰符:用于修饰类中的成员(成员变量,成员函数)。被私有的成员只在本类中有效。
应用:
将成员变量私有化以后,类以外即使建立了对象也不能直接访问。可以对外提供对应的set ,get方法对其进行访问。在方法中加入逻辑判断等语句,对访问的数据进行操作,提高代码健壮性和对数据访问的安全性。

注意:
私有仅仅是封装的一种表现形式。函数是Java中最小的封装体。

2. 构造函数

2.1 概述
对象一建立就会调用与之对应的构造函数给对象初始化。初始化完成后,构造函数不能像普通函数那样被对象调用。构造函数函数名与类名相同;不用定义返回值类型;不可以写return语句。当一个类中没有定义构造函数时,那么系统会默认给该类加入一个空参数的构造函数。当在类中自定义了构造函数后,默认的构造函数就没有了。默认构造函数的权限和所属类一致。默认构造函数的权限是随着的类的变化而变化的。

2.2 构造函数与一般函数的区别:
(1)写法上的不同
构造函数的函数名与类名相同;不用定义返回值类型;不可以写return语句。
一般函数需要定义返回值类型,只有当返回值类型是void并且return语句在函数最后一行时才可以省略不写。
(2)运行上的不同
构造函数是在对象一建立就运行。给对象初始化。一个对象建立,构造函数只运行一次。
而一般方法是对象调用才执行,给是对象添加对象具备的功能。可以被该对象调用多次。
(3)调用上的不同
构造函数可以调用一般函数。
一般函数不可以调用构造函数(因为构造函数中有this语句和super语句,而this语句和super语句只能存在于构造函数的第一行)。

2.3 构造代码块。
对象一建立就运行,而且优先于构造函数执行。
作用:给所有本类对象进行初始化。

2.4 构造代码块和构造函数的区别:
构造代码块是给本类中所有对象进行统一初始化,而构造函数是给本类中对应的对象初始化。构造代码块中定义的是不同对象共性的初始化内容。

3. this 关键字和 super 关键字

3.1 this 关键字
this代本类对象的引用。即其所在函数所属对象的引用。哪个对象在调用this所在的函数,this就代表哪个对象。在同一类中,this可以省略,但当变量出现同名情况时,一定要加this。本类中非静态前省略了this,静态前省略了类名。this的应用:当定义类中功能时,该函数内部要用到调用该函数的对象时,这时用this来表示这个对象。但凡本类功能内部使用了了本类对象,都用this表示。

3.2 this 语句
用于构造函数之间进行互相调用。
this语句只能定义在构造函数的第一行。因为初始化要先执行。

3.3 super 关键字
和this的用法几乎一致。this代表本类对象的引用;super代表父类对象的引用,即父类的内存空间的标识。当子父类出现同名成员时,可以用super进行区分,子类要调用父类指定构造函数时,可以使用super。

3.4 super 语句
子类中所有的构造函数默认第一行都有一条隐式的语句 super();它会访问父类中空参数的构造函数。子类构造函数也可以通过this语句访问本类中的构造函数。但是子类中肯定至少有一个构造函数会访问父类。super语句一定定义在子类构造函数的第一行。this语句也是只能放在第一行,所以在同一个构造函数内只能存在一个this或一个super语句,二者不能共存。

◆◆◆◆◆【4 static 关键字】◆◆◆◆◆

static:成员修饰符,静态。用于修饰成员(成员变量和成员函数)

4.1 概述
(1)static特点:
1)随着类的加载而加载。也就是说:静态会随着类的消失而消失。说明它的生命周期最长。
2)优先于对象存在。静态是先存在的。对象是后存在的。
3)被所有对象所共享。
4)可以直接被类名所调用。格式:类名.静态成员。

(2)实例变量和类变量的区别:
成员变量又叫实例变量,被static修饰的成员变量又叫类变量。
1)存放位置。
类变量随着类的加载而存在于方法区中。
实例变量随着对象的建立而存在于堆内存中。
2)生命周期:
类变量生命周期最长,随着类的消失而消失。
实例变量生命周期随着对象的消失而消失。

(3)成员变量和局部变量的区别:
成员变量又叫实例变量。
1)作用范围
成员变量定义在类中,作用于整个类中。
局部变定义在局部范围内,只作用于局部范围(如函数内或者语句中)。
2)在内存中的位置:
成员变量随着对象的建立而建立在对象所在的堆内存中,随着对象的消失而消失。
局部变量存在于栈内存中。作用的范围结束,变量空间会自动释放。
3)默认初始化值
成员变量有默认初始化值。
局部变量没有默认初始化值。

4.2 什么时候使用静态?
静态有利有弊。
利处:对对象的共享数据进行单独空间的存储,节省空间,没有必要每一个对象中都存储一份;可以直接被类名调用。
弊端:生命周期过长;访问出现局限性。(静态虽好,只能访问静态)
要从两方面下手,静态修饰的内容有成员变量和成员函数。
(1)什么时候定义静态变量(类变量)呢?
当对象中出现共享数据时,该数据被静态所修饰。对象中的特有数据要定义成非静态存在于堆内存中。
(2)什么时候定义静态函数呢?
当功能内部没有访问到非静态数据(对象的特有数据),那么该功能可以定义成静态的。
注意:
a.静态方法只能访问静态成员。非静态方法既可以访问静态成员也可以访问非静态成员。
b.静态方法中不可以定义this,super关键字。因为静态优先于对象存在。所以静态方法中不可以出现this。

4.3 静态代码块

格式:
static
{
    静态代码块中的执行语句。
}
特点:随着类的加载而执行,只执行一次,并优先于主函数(如果本类中有主函数)。用于给类进行初始化的。

◆◆◆◆◆【5. 单例设计模式】◆◆◆◆◆

设计模式:解决某一类问题最行之有效的方法。java中有23种设计模式:单例设计模式用于实现一个类在内存只存在一个对象。

5.1 如何定义单例设计模式
(1)为了避免其他程序过多建立该类对象。先将构造函数私有化,禁止其他程序建立该类对象。
(2)为了让其他程序可以访问到该类对象,只好在本类中,创建一个本类对象。
(3)为了方便其他程序对自定义对象的访问,可以对外提供一个方法获取到该对象。
(4)对于事物该怎么描述,还怎么描述。当需要将该事物的对象保证在内存中唯一时,就将以上的三步加上即可。

5.2 代码体现

5.2.1 方法一 饿汉式
先初始化对象。Single类一进内存,就已经创建好了对象。

1 class Single
2 {
3     private static final Single s = new Single();
4     private Single(){}
5     public static Single getInstance()
6     {
7         return s;
8     }
9 }


5.2.2 方法二 懒汉式
对象在方法被调用时,才初始化,也叫做对象的延时加载。Single类进内存,对象还没有存在,只有调用了getInstance方法时,才建立对象。

 1 class Single
 2 {
 3     private static Single s = null;
 4     private Single(){}
 5     public static Single getInstance()
 6     {
 7         if(s==null)
 8         {
 9             synchronized(Single.class)
10             {
11                 if(s==null)
12                     s = new Single();
13             }
14         }
15         return s;
16     }
17 }

 


原则:
定义单例,建议使用饿汉式。因为它简单安全。

◆◆◆【6.对象的建立在内存中的体现 】◆◆◆
Person p = new Person("zhangsan",20);
该句话都做了什么事情(暂时不考虑方法区)?
(1)在栈内存主函数main的空间内开辟空间,定义一个引用型变量p
(2)因为new用到了Person.class.所以会先在硬盘中找到Person.class文件,通过java虚拟机加载到内存并开辟了堆内存空间
(3)执行该类中的static代码块,如果有的话,给Person.class类进行初始化。
(4)在堆内存中开辟空间,分配内存地址。
(5)在堆内存中建立对象的特有属性。并进行默认初始化。
(6)对属性进行显示初始化。
(7)对对象进行构造代码块初始化。
(8)对对象进行对应的构造函数初始化。
(9)将内存地址赋给栈内存中的p变量。

####################################################################################
三 面向对象的特征(二) 继承 Inheritance
####################################################################################

1.概述
多个类中存在相同属性和行为时,将这些内容抽取到单独一个类中,那么多个类无需再定义这些属性和行为,只要继承那个类即可。多个类可以称为子类,单独这个类称为父类或者超类。子类可以直接访问父类中的非私有的属性和行为。通过 extends 关键字让类与类之间产生继承关系。

特点:继承的出现提高了代码的复用性。让类与类之间产生了关系,提供了多态的前提。
(1)Java只支持单继承,不支持多继承。一个类只能有一个父类,不可以有多个父类。因为多继承容易带来安全隐患:当多个父类中定义了相同功能,当功能内容不同时,子类对象不确定要运行哪一个。所以java不支持多继承,但将这种机制换成另一个种安全的方式来体现,多实现。
(2)Java支持多层继承,形成一个继承体系.想要使用体系功能:查阅父类功能,建立子类对象调用功能。查阅父类功能是因为父类中定义的是该体系中共性功能。通过了解共性功能,就可以知道该体系的基本功能。那么这个体系已经可以基本使用了。创建最子类的对象调用功能是因为有可能父类不能创建对象,而且创建子类对象可以使用更多的功能,包括基本的也包括特有的。

2. 继承中成员的特点:

2.1 子父类中的变量
如果子类中出现非私有的同名成员变量时,子类要访问本类中的变量,用this;子类要访问父类中的同名变量,用super。一般不会出现这种情况,因为父类中有了,子类不需要定义。而且父类定义时,一般变量都私有化。

2.2 子父类中的函数。
子类可以直接访问父类中非私有的成员函数。特殊情况:当子类中定义了与父类一模一样的方法时,会发生覆盖操作。这时当子类对象调用该函数,会运行子类函数的内容。覆盖只是一种形象的说法,其实父类的方法还在内存当中,只是没有被执行而已。

◆◆◆◆【函数覆盖(Override)】◆◆◆◆
子类中出现与父类一模一样的方法时,会出现覆盖操作,也称为重写或者复写。
(1)什么时候使用覆盖:
当父类的功能要被修改时,不建议修改源码。因为是灾难。只要通过一个类继承原有类,定义一个新的升级后的功能即可。但是功能是相同的,只是实现方法改变。这时子类可以沿袭父类中的功能定义,并重写功能内容。
(2)重载与重写的区别
重载:存在于同一类中函数与函数之间,只看同名函数的参数列表。
重写:存在于父类与子类的函数之间,子父类方法要一模一样(权限修饰符子类要大于父类)。
注意:
a. 子类覆盖父类,必须保证子类权限大于等于父类权限,才可以覆盖,否则编译失败。
b. 父类中的私有方法不会被覆盖,子类不可以具备父类中私有的内容。
c. 在子类覆盖方法中,继续使用被覆盖的方法可以通过super.函数名获取。


你发现了吗?
在多态中的覆盖有些不一样哦
1.非多态的静态方法覆盖后,运行的是子类中的静态方法;多态中静态方法覆盖后,运行的还是父类中的静态方法。
2.非多态的成员变量覆盖后,调用的是子类中的成员变量;多态中成员变量覆盖后,调用的还是父类中的成员变量。
3.非多态的函数覆盖要求子类权限要大于等于父类,其它名称要一致;多态中函数覆盖返回值也可以有所不同,但是有关系。如父类方法的返回值是父类类型,子类方法的返回值类型可以是子类类型。

2.3 子父类中的构造函数。
构造函数可以给本类进行对象初始化,也可以给子类对象进行初始化。在对子类对象进行初始化时,父类的构造函数也会运行,那是因为子类中所有的构造函数默认第一行有一条隐式的语句 super();super语句会访问父类中空参数的构造函数。

(1)为什么子类一定要访问父类中的构造函数?
因为子类可以直接获取父类中的数据,所以必须要先明确父类对数据的初始化过程。子类对象在建立时,需要先查看父类是如何对这些数据进行初始化的。所以子类在对象初始化时,要先访问一下父类中的构造函数。当父类中没有空参数构造函数时,子类构造函数必须通过手动定义super语句来明确要访问的父类中指定的构造函数。

(2)子类的实例化过程
子类会具备父类中的数据,所以要先明确父类是如何对这些数据初始化的。子类的所有的构造函数,默认都会访问父类中空参数的构造函数。因为子类每一个构造函数内的第一行都有一条默认的语句super();当父类中没有空参数的构造函数时,子类的构造函数必须通过this或者super语句指定要访问的构造函数。子类中至少有一个构造函数会访问父类中的构造函数。这是一定的,否则编译失败。

3. final 关键字

final: 最终。修饰符,可以修饰类,函数,变量。
(1)被final修饰的类不可以被继承。
(2)被final修饰的方法不可以被复写。
(3)被final修饰的变量是一个常量只能赋值一次,既可以修饰成员变量,也可以修饰局部变量。
(4)内部类定义在类中的局部位置上时,只能访问该局部被final修饰的局部变量。
注意:
当在描述事物时,一些数据的出现值是固定的,那么这时为了增强阅读性,都给这些值起个名字。方便于阅读。而这个值不需要改变,所以加上final修饰。作为常量。

4. 抽象类

(1)定义:
Java中可以定义没有方法体的方法,该方法的具体实现由子类完成,该没有功能主体的方法称为抽象方法,包含抽象方法的类就是抽象类。抽象是从多个事物中将共性的,本质的内容抽取出来。
格式:修饰符 abstract 返回值类型   函数名(参数列表);

(2)抽象的特点
1)抽象方法只有方法声明,没有方法体。抽象方法一定在抽象类中,因为抽象函数所在类,也必须被抽象标识。
2)抽象方法和抽象类都必须被abstract关键字修饰。
3)抽象类不可以实例化,也就是不可以用new创建对象。
4)抽象类中的抽象方法要被使用,必须通过其子类实例化,让子类复写所有的抽象方法后才可以建立子类对象调用。如果子类只覆盖了部分抽象
   方法,那么该子类还是一个抽象类。

(3)抽象类与一般类的区别
抽象类也有构造函数,因为抽象类是一个父类,要给子类提供实例的初始化。在抽象类中可以定义抽象方法(也可以不定义抽象方法,这样做仅仅是不让该类建立对象)。抽象类不可以实例化,也就是说不能建立对象。

◆◆◆◆◆【5.模板方法设计模式】◆◆◆◆◆

在定义功能时,功能的一部分是确定的,但是有一部分是不确定,而确定的部分在使用不确定的部分,那么这时就将不确定的部分暴露出去。由
该类的子类去完成。
需求:获取一段程序运行的时间。
原理:获取程序开始和结束的时间并相减即可。获取时间:System.currentTimeMillis();当代码完成优化后,就可以解决这类问题。这种方式就是模版方法设计模式。

 1 abstract class GetTime
 2 {
 3     public final void getTime()
 4     {
 5         long start = System.currentTimeMillis();
 6 
 7         runcode();
 8 
 9         long end = System.currentTimeMillis();
10 
11         System.out.println("毫秒:"+(end-start));
12     }
13     public abstract void runcode();
14 }
15 class SubTime extends GetTime
16 {
17     public void runcode()
18     {
19         for(int x=0; x<4000; x++)
20         {
21             System.out.print(x);
22         }
23     }
24 }
25 class  TemplateDemo
26 {
27     public static void main(String[] args)
28     {
29         SubTime gt = new SubTime();
30         gt.getTime();
31     }
32 }

6. 接口

6.1 格式特点
(1)通过interface来定义。
(2)接口中常见成员:常量,抽象方法。而且这些成员都有固定的修饰符。常量: public static final 方法: public abstract
(3)接口中的成员都是公有的。以上固定修饰符如果不写或漏写,系统会自动加上的,不影响运行,但是建议写全,方便于阅读。
(4)一个类可以对接口进行多实现,也弥补了多继承带来的安全隐患,所以java对多继承进行了改良。用多实现方法来体现多继承的特性。
(5)类与接口之间是实现关系,一个类可以在继承一个类的同时实现多个接口。
(6)接口与接口之间是继承关系,而且可以多继承。(不同父类接口如果有同名方法的话,它们的返回值类型必须一致,否则编译报错)
注意:
接口不可以创建对象,因为有抽象方法。需要被子类实现,子类对接口中的抽象方法全都覆盖后,子类才可以实例化。否则子类是一个抽象类。

6.2 为什么java不支持多继承却支持多实现呢?
因为多继承会带来安全隐患,由于多继承中的父类有方法体,当方法定义相同但方法体不同时,子类调用时会产生问题;而多实现由于接口中都没
有方法体,可以由子类任意定义,所以不会出现该问题。

6.3 接口与抽象类的区别
相同点:
(1)都是不断抽取出来的抽象的概念,都可以在内部定义抽象方法。
(2)通常都在体系的顶层。
(3)都不可以实例化,都需要子类来实现。
不同点:
(1)抽象类中可以定义抽象方法和非抽象方法,而接口中只能定义抽象方法,接口中的成员都有固定修饰符
(2)抽象类体现继承关系,一个类只能单继承;接口体现实现关系,一个类可以多实现。也就是说,接口的出现避免了单继承的局限性。
(3)抽象类是继承,是 "is a "关系;接口是实现,是 "like a"关系

总结
基本功能定义在抽象类中,扩展功能定义在接口中

####################################################################################
四 面向对象的特征(三) 多态 Polymorphism
####################################################################################

1.概述

(1)定义:某一类事物的多种体现形态。
(2)多态的体现:父类的引用指向了自己的子类对象或者父类的引用接收了自己的子类对象。
(3)多态的两个前提:必须是类与类之间有继承或者实现关系;必须存在覆盖操作。
(4)好处:多态的出现大大的提高了程序的扩展性和后期可维护性。
(5)弊端:虽然提高了扩展性,但是只能使用父类的引用访问父类中的成员。

2.多态中成员的特点

(1)在多态中,非静态成员函数的特点:
在编译时期:参阅引用型变量所属的类中是否有调用的函数。如果有,编译通过,如果没有编译失败。
在运行时期:参阅对象所属的类中是否有调用的函数。
简单总结就是:成员函数在多态调用时,编译看左边,运行看右边。
(2)在多态中,静态成员函数的特点:
无论编译和运行,都参考做左边(引用型变量所属的类)。
(3)在多态中,成员变量的特点:
无论编译和运行,都参考左边。

代码示例

 1 class Fu
 2 {
 3     static int num = 5;
 4     void method1()
 5     {
 6         System.out.println("fu method_1");
 7     }
 8     void method2()
 9     {
10         System.out.println("fu method_2");
11     }
12     static void method4()
13     {
14         System.out.println("fu method_4");
15     }
16 }
17 class Zi extends Fu
18 {
19     static int num = 8;
20     void method1()
21     {
22         System.out.println("zi method_1");
23     }
24     void method3()
25     {
26         System.out.println("zi method_3");
27     }
28 
29     static void method4()
30     {
31         System.out.println("zi method_4");
32     }
33 }
34 class  Demo
35 {
36     public static void main(String[] args)
37     {
38         
39         Fu f = new Zi();
40         System.out.println(f.num);    //打印结果Fu.num 5
41         Zi z = new Zi();
42         System.out.println(z.num);    //打印结果Zi.num 8
43         f.method1();    //打印结果zi.method_1
44         f.method2();    //打印结果fu.method_2
45         //f.method3();    //编译失败,找不到method3
46         f.method4();    //打印结果fu.method_4
47     }
48 }

 


◆◆◆【3.转型】◆◆◆

向上转型:父类引用指向子类对象
向下转型:强制将父类的引用转成子类类型。

Animal a=new Cat();
//向上转型,类型提升
a.eat();
Cat c = (Cat)a;
//向下转型,强制将父类引用转成子类类型
c.catchMouse();

千万不要将父类对象转成子类类型。我们能转换的是父类的引用指向了自己的子类对象时,该引用可以被提升,也可以被强制转换。多态自始至终都是子类对象在做着变化。

你发现了吗?
转型的原理和数据类型的自动提升和强制转换的原理其实是一样的。

4. instanceof 关键字

用于判断对象的类型。判断某一类型引用指向的对象,到底符合什么类型(类型为类类型或接口类型)的时候,用这个关键字。
格式:对象 intanceof 类型

使用instanceof的两种情况:
(1)子类型有限
(2)当传的类型需要进行其它操作(如比较)时,必须要确定它到底是哪种子类型,才能调用它的特有方法来比较。

5. 内部类

当描述事物时,事物的内部还有事物,该事物用内部类来描述。因为内部事物在使用外部事物的内容。将一个类定义在另一个类的里面,对里面那个类就称为内部类(内置类,嵌套类)。内部类全名: 外部类.内部类

5.1 内部类的访问特点:
(1)内部类可以直接访问外部类中的成员,包括私有。因为内部类中持有了一个外部类的引用,格式 外部类名.this.
(2)外部类要访问内部类,必须建立内部类对象。

5.2 内部类的访问格式(按内部类位置分)

5.2.1 内部类定义在成员位置上

(1)当内部类定义在外部类的成员位置上,而且非私有,可以在外部其他类中直接建立内部类对象。
外部类名.内部类名  变量名 = 外部类对象.内部类对象; Outer.Inner in = new Outer().new Inner();
(2)当内部类在成员位置上,就可以被成员修饰符所修饰。
private :将内部类在外部类中进行封装。
static  :当内部类被static修饰后,只能直接访问外部类中的static成员(静态里不能有Outer.this.)。出现了访问局限。
            在外部其他类中,直接访问static内部类的非静态成员: new Outer.Inner().function();
            在外部其他类中,直接访问static内部类的静态成员  : Outer.Inner.function();
注意:
当内部类中定义了静态成员,该内部类必须是static的。当外部类中的静态方法需要访问内部类时,内部类也必须是static的。

5.2.2 内部类定义在局部位置上
(1)不可以被成员修饰符修饰,因为public/static等成员修饰符只能修饰成员,不能修饰局部。
(2)可以直接访问外部类中的成员,因为还持有外部类中的引用,但是只能所在局部访问被final修饰的变量。
(3)内部类内部不能定义静态成员,因为当内部类中定义了静态成员,该内部类必须是static的。

◆◆◆【5.3 匿名内部类】◆◆◆

(1)匿名内部类其实就是内部类的简写格式。
(2)定义匿名内部类的前提:内部类必须是继承一个类或者实现接口。
(3)匿名内部类的格式:  new 父类或者接口(){覆盖父类或接口中的方法,也可以定义子类的内容}
(4)匿名内部类就是建立一个带内容的外部类或者接口的子类匿名对象,这个对象有点胖。
(5)匿名内部类中定义的方法最好不要超过2个。
注意:
    当没有父类时,可以使用object类作为父类使用。

代码示例
补足代码,通过匿名内部类

 1 interface Inter
 2 {
 3     void method();
 4 }
 5 class Test
 6 {
 7     //代码部分
 8 }
 9 class  LianXi
10 {
11     public static void main(String[] args)
12     {
13         Test.function().method();
14     }
15 }
16 
17 */
18 /*
19 //代码部分
20     static Inter function()
21     {
22         return new Inter()
23         {
24             public void method()
25             {
26                 System.out.println("method run");
27             }
28         };
29     }
posted @ 2013-07-03 14:50  赵晨光  阅读(347)  评论(0编辑  收藏  举报
---------------------- ASP.Net+Android+IOS开发.Net培训、期待与您交流! ------- --------------- 详细请查看:http://edu.csdn.net