---------------------- ASP.Net+Android+IO开发S、.Net培训、期待与您交流! ----------------------
面向对象
万物皆对象。
面向对象是相对面向过程而言:面向对象和面向过程都是一种思想。面向过程强调的是功能行为;面向对象是将功能封装进对象,强调具备了功能的对象。
面向对象是基于面向过程的。
面向对象的特征:封装,继承,多态。
以后开发:其实就是找对象使用,没有对象,就创建对象。
找对象:建立对象,使用对象,维护对象的关系。
举例:
现实中的对象:张三,李四。
想要描述:提取对象中的共性内容,对具体进行抽象。
共性内容:姓名、年龄、性别等。
类和对象的关系:
类:对显示生活中的事物的描述。
对象:就是这类事物,实实在在的个体。
成员变量和局部变量:
作用域:成员变量作用于整个类中,局部变量作用于函数中或语句中。
在内存中的位置:成员变量在堆内存中,局部变量在栈内存中。
生命周期:成员变量随着类的创建而创建,存在堆内存中,随着类的消失而消失。
局部变量随着方法调用或者语句执行而存放在栈内存中,调用结束后或语句结束后自动释放。
class Person
{
private String name; // 成员变量
public void study()
{
int a = 1;//局部变量
}
}
匿名对象:
匿名对象是对象的简化形式。
匿名对象两种使用情况:
<1>当对对象方法仅进行一次调用的时候。可以用匿名对象来完成,这样写比较简化。
如果对一个对象进行多个成员调用,必须给这个对象起个名字。
<2>匿名对象可以作为实际参数进行传递。
举例匿名对象的实现:new Car().num = 5;
show(new Car());
封装(Encapsulation)
封装:是指隐藏对象的属性和实现细节,仅对外提供公共的访问方式。
好处是:将变化隔离,便于使用,提高重用性,提高安全性。
封装的原则:将不需要对外提供的内容都隐藏起来。
把属性都隐藏,提供公共方法对其访问。
private:私有,权限修饰符。用于修饰类中的成员(成员变量,成员函数),私有只有在本类中有效。将成员变量私有化后,类以外即使建立了对象也不能直接访问。要想访问,需要在Person类中提供对应访问age的访问方式。之所以对外提供访问方式,就因为可以在访问方式中加入逻辑判断语句。对访问数据进行操作,提高代码的健壮性。
封装不是私有,私有仅仅是封装的一种表现形式。
构造函数
特点:
1.函数名与类名相同。
2.不用定义返回值类型。
3.不可以写return语句。
作用:给对象初始化。
注意:
1.默认构造函数的特点。
2.多个构造函数是以重载的形式存在的。
对象一建立就会调用与之对应的构造函数,当类中没有定义构造函数时,那么系统会默认给该类加入一个空参数的构造函数(方便初始化)。当在类中定义构造函数时,默认的构造函数就消失了。
构造函数和一般函数在写法上有不同,在运行上也有不同。构造函数在对象一建立就运行,给对象初始化。而一般函数是在对象调用才执行,是给对象添加对象具备的功能。一个对象建立,构造函数只能运行一次,而一般函数可以被调用多次。
什么时候定义构造函数呢?
当分析事物,该事物具备一些特征或行为,那么将这些内容定义在构造函数中。
构造代码块:
作用:给对象初始化。对象一建立就运行,而且优先于构造函数执行。
和构造函数的区别是:构造代码块是给所有对象进行统一初始化,而构造函数是给对应的对象初始化。
构造代码块中定义的是不同对象共性的初始化对象。
This:
看上去是用于区*部变量和成员变量重名的问题。
This为什么能解决这个问题?代表什么呢?
this代表它所在函数所属对象的引用。简单说,哪个对象在调用this所在的函数,this就代表那个对象。
this的应用:当定义类中的功能,该函数内部要用到调用该函数的对象时,这时用this来表示这个对象。
本类功能内部使用到本类对象,都用this表示。
this语句:用于构造函数之间进行互相调用;
this(name)只能定义在构造函数的第一行。因为初始化要先运行。
class Person
{
private String name; // 成员变量
private int age;
Person(String name)
{
this.name = name;
}
Person(String name,int age)
{
//this.name = name;
this(name);//调用构造函数。
this.age = age;
}
static(静态)关键字
static 关键字:用于修饰成员(成员变量和成员函数)
被修饰后的成员具备以下特点:
<1>随着类的加载而加载;也就是说静态会随着类的消失而消失,它的生命周期最长。
<2>优先于对象存在;静态先存在,然后再是对象。
<3>被所有对象所共享;
<4>可以直接被类名调用。
使用注意:
<1>静态方法只能访问静态成员。
<2>静态方法不可以写this,super关键字。
<3>主函数是静态的。
static用于修饰成员,不需要每个成员都存储。
当成员被静态修饰后,就多了一个调用方式,除了可以被对象调用外,还可以直接被类名调用。类名.成员对象。
方法区(共享区,数据区):用于存储类中的方法,共享数据。
实例变量和类变量的区别:
1.存放位置:类变量随着类的加载而存在于方法区中。实例变量随着对象的建立而存在于堆内存中。
2.生命周期:类变量生命周期最长,随着类的消失而消失。实例变量生命周期随着对象的消失而消失。
3.主函数是静态的。
静态使用的注意事项:
1.静态方法只能访问静态成员,非静态方法既可以访问静态也可以访问非静态。
2.静态方法中不可以定义this,super关键字。因为静态优先于对象存在,所以静态方法中不可以出现this。
静态有利有弊:
利:对对象共享数据进行单独空间的存储,节省空间。没有必要每个对象中都存储一份。可以直接被类名调用。
弊:生命周期过长,访问会出现局限性(静态虽好,只能访问静态)
主函数:是一个特殊函数,作为程序的入口,可以被JVM调用。
主函数定义:
public:代表该函数的访问权限最大。
static:代表主函数随着类的加载就已经存在了。
void:主函数没有具体的返回值。
main:不是关键字,但是一个特殊的单词,可以被JVM识别。
(String[] args):函数的参数,参数类型是一个数组,该数组中的元素是字符串,字符串类型的数组。
主函数是固定格式的:JVM识别。唯一可以改变的是args。Arguments参数。
JVM调用主函数时,传入的是new String[0];
什么时候使用静态?要从两个方面下手,因为静态修饰内容有成员变量和成员函数。
什么时候定义静态的变量呢?
当对象中出现共享数据时,该数据被静态所修饰,对象中特有数据要定义成非静态存在于堆内存中。
什么时候定义静态的函数呢?
当功能内部没有访问到非静态数据(对象的特有数据),那么该功能可以定义成静态的。
代码:
class Person
{
String name;//成员变量,实例变量,需要对象存在
static String country = "CN";//类变量,类存在就存在
/*Person()
{
}
Person(String name)
{
this.name = name;
}*/
public void show()
{
System.out.println("name="+name+",country="+country);
}
}
class StaticDemo
{
public static void main(String[] args)
{
Person p = new Person();
p.name = "zhangsan";
p.show();
//System.out.println(p.country);
}
}
静态的应用:每一个应用程序中都有共性的功能,可以将这些功能进行抽取,独立封装。以便复用。
/*
定义一个数组的工具类,包括的功能:求最大者,最小值,选择排序,冒泡排序,折半查找。
*/
class ArrayTool
{
/*私有化构造函数,防止定义无效的对象*/
private ArrayTool()
{
}
/*求最大值的函数*/
public static int getMax(int[] arr)
{
int max = arr[0];
for ( int i = 1; i < arr.length ;i++ )
{
if(arr[i]> max)
max = arr[i] ;
}
return max;
}
/*求最小值*/
public static int getMin(int[] arr)
{
int min = arr[0];
for ( int i = 1; i < arr.length ;i++ )
{
if(arr[i]< min)
min = arr[i] ;
}
return min;
}
/*选择排序*/
public static void selectSort(int[] arr)
{
for (int x = 0; x < arr.length-1 ; x++)
{
for (int y = x + 1; y < arr.length ; y++ )
{
if(arr[x] > arr[y])
swap(arr,x,y);
}
}
}
/*冒泡排序*/
public static void bubbleSort(int[] arr)
{
for (int x = 0; x <arr.length -1 ; x++ )
{
for (int y = 0;y <arr.length-x-1 ;y++ )
{
if (arr[y+1] < arr[y])
swap(arr,y,y+1);
}
}
}
/*交换函数,只给排序用,也只作用于本类中,可以私有它*/
private static void swap(int[] arr,int a,int b)
{
int temp = arr[a];
arr[a] = arr[b];
arr[b] = temp ;
}
/*折半查找*/
public static int halfSearch(int[] arr,int num)
{
int min = 0 ;
int max = arr.length -1;
int mid = (min+max)/2;
while (min < max)
{
if(arr[mid] < num)
min = mid ;
else if (arr[mid] > num)
max = mid ;
else
return mid;
}
return -1;//数组中找不到这个数
}
/*写一个打印函数*/
public static void printArray(int[] arr)
{
System.out.print("[");
for (int i = 0; i < arr.length ; i++ )
{
System.out.print(arr[i]+",");
}
System.out.println("]");
}
}
class ArrayToolDemo{public static void main(String[] args) {int[] arr = new int[]{1,2,5,8,3,4,8,9};//int index = ArrayTool.halfSearch(arr,8);System.out.println("index="+index);ArrayTool.printArray(arr);ArrayTool.selectSort(arr);ArrayTool.printArray(arr);ArrayTool.bubbleSort(arr);ArrayTool.printArray(arr);System.out.println("min="+ArrayTool.getMin(arr));System.out.println("max="+ArrayTool.getMax(arr));}}
我们发现:虽然可以通过建立ArrayTool的对象使用这些工具方法对数组进行操作。但问题是:
1.对象是用于封装数据的。可是ArrayTool对象并未封装特有数据。
2.操作数组的每一个方法都没有用到ArrayTool对象中的特有数据。
这是我们考虑,让程序更严谨,要不需要对象的。
可以将ArrayTool中的方法都定义成static的,直接通过类名调用即可。
将方法都静态后,可以方便于使用,但是该类还是可以被其他程序建立对象的。为了严谨,强制该类不能建立对象。
可以通过将构造函数私有化完成。
一个类中默认会有一个空参数的构造函数,这个默认的构造函数的权限和所属类一致。
如果类被public修饰,那么默认的构造函数也带public修饰符。如果类没有被public修饰,那么默认的构造函数,也没有被public修饰。
默认构造函数的权限是随着类的变化而变化的。
静态代码块
格式:
static
{
静态代码块中的执行语句;
}
特点:随着类的加载而执行,只执行一次。用于给类初始化。并优先于主函数。
class StaticCode
{
private int age = 1;// 显示初始化
StaticCode()
{
System.out.println('b');//无对象的构造函数
}
static
{
System.out.println('a');//静态代码块
}
{
System.out.println(age);//构造代码块
}
StaticCode(int age)
{
this.age = age;
System.out.println('d');//有构造函数给对应对象初始化
System.out.println(age);
}
public static void show()
{
System.out.println("show");
}
}
class StaticCodeDemo
{
/*static
{
System.out.println('b');
}*/
public static void main(String[] args)
{
//new StaticCode();//匿名对象?
//new StaticCode();
//StaticCode.show();
//StaticCode s = null;// 不加载类。
new StaticCode(1);
System.out.println("Hello World!");
}
/*static
{
System.out.println('c');
}*/
}
优先级: 静态代码块初始化>默认初始化>显示初始化>构造代码块初始化>构造函数初始化
运行机制:
<1> 因为new用到了Person.class,所以会找到Peron.class文件并加载到内存中。
<2>执行该类中的static代码块,如果有的话,该Person.class类进行初始化。
<3>在堆内存中开辟空间,分配内存地址。
<4>在堆内存中建立对象的特有属性。并进行默认初始化。
<5>对属性进行显示初始化。
<6>对对象进行构造代码块初始化。
<7>对对象进行对应的构造函数初始化。
<8>将内存地址赋给占内存的p变量。
非静态(省略this点)方法调用过程:(p.setName的调用)
1. 在栈内存中开辟setName,里边存this(指向将要调用这个函数的对象)和 name;
2. This 指向P,所以将p指向的地址就给了this。
3. This就指向了堆内存中的对象。
4. Name就指向了内存中的name,并对他进行了修改。
静态(省略类名点)(showCountry),用类名调用,与堆内存无关。
继承
将类中的共性提取出来,单独封装,搞个父类用于继承。
继承:1.提高代码的复用性;2,.继承让类与类直接产生了关系,有了这个关系才有了多态的特征。
注意:千万不要为了获取其他类的功能,简化代码而继承。必须是类与类直接有所属关系才可以继承。所属关系:is a。
java语言中:java只支持单继承,不支持多继承。
因为多继承容易带来安全隐患,当多个父类定义了相同功能,而功能内容不容时,子类对象不确定要运行哪一个。
但是java保留了这种机制,并用另一种体现形式来表示:多实现。
java支持多层继承。也就是一个继承体系。
如何使用一个继承体系中的功能呢?想要使用体系,先查阅体系中的父类的描述,因为父类中定义的是该体系中的共性功能。通过了解共性功能,就可以知道该体系的基本功能。通过了解共性功能,就可以知道该体系的基本功能。那么这个体系已经基本可以使用了。那么在具体调用时,要创建最子类的对象,为什么呢?
1.是因为有可能父类不可能创建对象。
2.是创建子类对象可以使用更多的功能,包括基本的,也包括特有的。
简单一句话:查阅父类功能,创建子类对象,使用功能。
如果父类和子类有相同的变量,打印的是子类的。
/* 子父类出现后,类成员特点
*/
class Fu
{
int num = 4;
}
class Zi extends Fu //zi类继承父类
{
int num = 5;
}
class ExtendsDemo2
{
public static void main(String[] args)
{
Zi z = new Zi();
System.out.println(z.num+"....."+z.num);
}
}
打印结果:5.....5
this代表本类对象的引用,super代表父类对象的引用。
子父类变量特点:如果子类中出现非私有的同名成员变量时,子类要访问本类中的变量,用this。
子类要访问父类中的同名变量时,用super。
super的使用和this几乎一致。this代表本类对象的引用,super代表父类对象的引用。
类中的成员包括:变量,函数,构造函数。
子父类中函数的特点:
当子类中出现和父类一模一样的函数时,当子类对象调用该函数,会运行子类函数的内容。如同父类的函数被覆盖一样。这种情况是函数的另一个特性:重写(覆盖)。
当子类继承父类,沿袭了父类的功能到子类中,但子类虽有该功能,但是功能内容却和父类不一致,这时没有必要定义新功能,而是使用覆盖特性,保留父类的功能定义,
并重写父类。可用于扩展。
子类覆盖父类,必须保证子类权限大于等于父类权限,才能覆盖,否则编译失败。
静态只能覆盖静态。
注意:
重载:只看同名函数的参数列表。
重写:子父类方法要一模一样。
class Fu
{
Fu()
{
System.out.println("Fu");
}
}
class Zi extends Fu
{
Zi()
{
//super();
System.out.println("zi");
}
}
class ExtendsDemo3
{
public static void main(String[] args)
{
Zi z = new Zi();
System.out.println("Hello World!");
}
}
程序会打印:Fu zi。
在对子类对象进行初始化时,父类的构造函数也会运行,那是因为子类的构造函数默认第一行有一条隐式语句super();
super():会访问父类中空参数的构造函数,而且子类中所有的构造函数默认第一行都是super()。
为什么子类一定要访问父类中的构造函数呢?
因为父类中的数据子类可以直接获取,所以子类对象在建立时,需要先查看父类中如何对数据进行初始化的。所以子类对象初始化时,需要先访问父类中的构造函数。如果要访问父类中指定的构造函数,可以通过手动定义super语句的方式来指定。
super()语句一定定义在子类构造函数的第一行。
<构造函数中this()与super()>只能有一个。子类中至少有一个构造函数访问父类。
子类的实例化过程。
结论:子类的所有的构造函数,默认都会访问父类中空参数的构造函数,因为子类每一个构造函数内的第一行都有一句隐式super();当父类中没有空参数的构造函数时,子类必须手动通过super语句形式来指定要访问父类中的构造函数。
当然:子类的构造函数第一行也可以手动指定this语句来访问本类中的构造函数。
子类中至少会有一个构造函数会访问父类中的构造函数。Object(所有类的父类)
final关键字
final:最终。作为一个修饰符。
<1>final可以修饰类,方法,变量。
<2>final修饰的类不可以被继承。
<3>final修饰的方法不可以被覆盖。
<4>final修饰的变量是一个常量。只能被赋值一次。
<5>内部类只能访问被final修饰的局部变量。
当在描述事物时,有些数据的出现值是固定的,那么这是为了增强阅读性,都给这些值起个名字。而这个值不需要改变,所以加上final修饰。作为常量:常量的书写规范所有字母都大写,如果由多个单词组成,单词间通过”_”连接。
目前为止,类有三个修饰符 public final 什么都不写。
抽象类:
当多个类中出现相同的功能,但功能主体不同,这时可以进行向上抽取。这时,只抽取功能定义,不抽取功能主体。
抽象类的特点:
1.抽象方法一定在抽象类中;
2.抽象方法和抽象类都必须被abstract关键字修饰;
3.抽象类不可以用new创建对象,因为调用抽象方法没意义。
4.抽象类中的方法要被使用,必须由子类复写所有的抽象方法后,建立子类对象调用。
如果子类只覆盖部分抽象方法,那么该子类还是一个抽象类。
抽象类和一般类没有太大的不同:该如何描述事物,就如何描述事物,只不过,该事物出现了一些看不懂的东西。这些不确定的部分,也是给事物的功能,需要明确出现,
但是无法定义主体,通过抽象方法来表示。抽象类比一般类多了个抽象函数。抽象类不可以实例化。
特殊:抽象类中可以不定义抽象方法,这样做仅仅不让该类建立对象。
abstract class Employee//定义一个抽象类
{
/*提取出姓名,ID,工资是员工和经理共有的,可以被继承*/
private String name ;
private String id;
private double pay;
Employee(String name,String id ,double pay)
{
this.name = name;
this.id = id;
this.pay = pay;
}
public abstract void work(); //工作方式,经理和员工不同,定义一个抽象方法
}
class Manager extends Employee
{
private int honus;
Manager(String name,String id ,double pay,int honus)
{
super(name,id,pay);//向上指向父类
this.honus = honus;//指向本类中的奖金
}
public void work()
{
System.out.println("Manager");
}
}
class Worker extends Employee
{
Worker(String name,String id ,double pay)
{
super(name,id,pay);
}
public void work()
{
System.out.println("worker");
}
}
class Compay
{
public static void main(String[] args)
{
Worker w = new Worker("lisi","1",2222);
w.work();
System.out.println("Hello World!");
}
}
获取一段程序运行的时间原理:获取程序开始和结束的时间并相减
获取时间: System。CurrentTimeMillis()
模板方法:
在定义功能时,功能的一部分是确定的,但是有一部分是不确定,而确定的部分在使用不确定的部分,那么这时就将不确定的部分暴露出去。由该类的子类去完成。
abstract class getTime
{
public final void getTime() //无法重写
{
long start = System.currentTimeMillis();
run();
long end = System.currentTimeMillis();
System.out.println("毫秒:"+(end - start));
}
abstract public void run();//抽象方法供子类调用
}
class DmRun extends getTime
{
public void run()
{
for (int i = 0;i < 10000 ;i++ )
{
System.out.print(i);
}
}
}
class Get
{
public static void main(String[] args)
{
DmRun d = new DmRun();
d.getTime();
System.out.println("Hello World!");
}
}
接口
接口的出现将”多继承“通过”多实现“来实现。
接口中的成员修饰符是固定的。
成员变量:public static final
成员函数:public abstract
接口:初期理解,可以认为是一个特殊的抽象类。当抽象类中的方法都是抽象的,那么该类可以通过接口的形式来表示。
接口中的成员都是public的。
接口:是不可以创建对象的,因为有抽象方法。需要被子类实现,子类对接口中的抽象方法全都覆盖后,子类才可以实例化。否则子类是一个抽象类。
interface Inter
{
public static final int num = 3;
public abstract void show();
}
class Test1
{
public void show()
{
System.out.println("父类");
}
}
class Test2 extends Test1 implements Inter
{
/*
public void show()
{
System.out.println("子类");
}*/
}
class InterDemo
{
public static void main(String[] args)
{
Test2 t = new Test2();
t.show();
System.out.println(t.num);
}
}
接口可以实现多实现。因为没有方法主体,可以由子类任意实现。
一个类只能继承一个类,同时也可以连接好几个接口
类与类之间是继承关系,类和接口是实现关系,接口和接口之间是继承关系。
接口的特点:
1.接口是对外暴露的规则。
2.接口是程序的功能扩展。
3.接口可以用来多实现。
4.类与接口之间是实现关系,而且类可以继承一个类的同时实现多个接口。
5.接口与接口之间可以有继承关系。
基本功能定义在类中,扩展功能在接口中。
interface Inner
{
void method();
}
class Test
{
/*补足代码,通过匿名内部类,
我先用内部类写,然后再简化*/
class Inners implements Inner
{
void method()
{
System.out.println("Inners");
}
}
public void function()
{
new Inners().method();
}
}
class InnerClassTest
{
public static void main(String[] args)
{
//Test.function().method();
Test.function();
System.out.println("Hello World!");
}
}
多态
定义:某一类事物的多种存在形态。
多态的表现:父类的引用指向了自己的子类对象。父类的引用也可以接受自己的子类对象。
多态的前提:必须是类与类之间有关系,要么继承,要么实现。通常还有一个前提:存在覆盖。
多态的好处:多态的出现大大的提高了程序的扩展性。
多态的弊端:提高了扩展性,但是只能使用父类中的引用访问父类中的成员。
多态的应用:
我们能转换的是父类应用指向了自己的子类对象时,该应用可以被提升,也可以被转换。多态自始至终都是子类对象在变化。
Instanceof :判断某一类型的引用指向什么类型。
在多态中的成员函数的特点:
在编译时期:参阅引用型变量所属的类中是否有调用方法。如果有,编译通过,如果没有,编译失败。
在运行时期:参阅对象所属的类中是否有调用方法。
简单总结就是:成员函数在多态调用时,编译看左边,运行看右边。
在多态中,成员变量的特点:无论编译和运行,都参考左边(引用型变量所属的类)。
在多态中,静态成员函数的特点,无论编译和运行,都参考左边。
PCI:
interface PCI
{
public void open();
public void close();
}
class MainBoard
{
public void run()
{
System.out.println("manboard run");
}
public void usePCI(PCI p)//接口型引用指向自己的子类对象(属于多态)PCI p = new NetCard();
{
if(p!=null)
{
p.open();
p.close();
}
}
}
class NetCard implements PCI
{
public void open()
{
System.out.println("NetCard open");
}
public void close()
{
System.out.println("NetCard close");
}
}
class SoundMusic implements PCI
{
public void open()
{
System.out.println("Music open");
}
public void close()
{
System.out.println("Music close");
}
}
/*class MainBoard
{
public void run()
{
System.out.println("mainboard run");
}
public void useNetCard(NetCard c)
{
c.open();
c.close();
}
}
class NetCard
{
public void open()
{
System.out.println("NetCard open");
}
public void close()
{
System.out.println("NetCard close");
}
}*/
class DuoTaiDemo7
{
public static void main(String[] args)
{
MainBoard mb = new MainBoard();
mb.run();
//mb.useNetCard(new NetCard());
mb.usePCI(null);
mb.usePCI(new NetCard());
mb.usePCI(new SoundMusic());
}
}
Object:超类,该类中定义的肯定是所有对象都具备的功能。
equals方法比较的哈希值。
object类中已经提供了对对象是否相同的比较方法,如果自定义类中也有比较相同的功能,没有必要重新定义。只要沿袭父类中的功能,建立自己特有的比较内容即可。这就是覆盖。
class Test //extends Object
{
private int num;
Test(int num)//定义Test构造函数,用于初始化
{
this.num = num;
}
public boolean equals(Test obj)//1.object obj = new test();多态2.重写了父类中的equals函数,为什么要重写呢,因为父类中的只能比较对象指向的地址。
{
if(!(obj instanceof Test))
return false;
Test t = (Test)obj;//将obj转回Test类型
return this.num ==t.num;//将调用这个函数的对象的num与要比较的对象的num进行比较。
}
}
class Demo1
{
public static void main(String[] args)
{
/*Test a = new Test();
Test b = new Test();
System.out.println(a.equals(b));*/// 由于对象a和对象b指向的不是相同的地址,所以输出false、
Test a = new Test(1);
Test b = new Test(1);
System.out.println(a.equals(b)); //比较两个对象成员的数值()
}
}
内部类
1.内部类可以直接访问外部类中的成员,包括私有成员。之所以内部类可以直接访问外部类中的成员,是因为内部类中持有了一个外部类的引用。
格式: 外部类名.this
2.外部类要访问内部类中的成员必须建立内部类的对象。
访问格式:
1.当内部类定义在外部类的成员位置上,而且非私有,可以在外部其他类中,可以直接建立内部类对象。
格式:外部类名.内部类名. 变量名 = 外部类对象.内部类对象
Outer.Inner in = new Outer().new Inner();
2.当内部类在成员位置上,就可以被成员修饰符所修饰。
比如,private:将内部类在外部类中进行封装。
static:内部类就具备了static的特性。当内部类被静态修饰后,只能访问外部类中的静态成员,就出现了访问局限。
在外部类中如何访问静态内部类?new Ourter.Inner().function();
在外部类中如何访问静态内部类中的静态成员呢? Ourter.Inner().function();
注意:当内部类中定义了静态成员,该内部类必须是静态的。
当外部类中静态方法访问内部类时,内部类必须是静态的。
/*当描述事物时,事物的内部还有事物,该事物用内部类来描述。因为内部事物在使用外部事物的内容。*/
Class Body
{
private class heart()
{
}
Public void show()
{
New heart();
}
}
局部内部类不能定义为静态。
内部类定义在局部时:
1. 不可以被成员修饰符修饰
2. 可以直接访问外部类中的成员,因为还持有外部类中的引用。但是不可以访问它所在的局部中的变量。只能访问被final修饰的局部变量。
匿名内部类:
1. 匿名内部类其实就是内部类的简写形式。
2. 定义匿名内部类的前提:内部类必须是继承一个类或者实现接口。
3. 匿名内部类的格式: new 父类或者接口(){定义子类的内容}.
4. 其实匿名内部类就是一个匿名子类对象。而且这个对象有点胖,也可以理解为带内容的对象。
5.匿名内部类中定义的方法最好不要超过3个。
---------------------- ASP.Net+Android+IO开发S、 .Net培训、期待与您交流! ----------------------