------- android培训、java培训、期待与您交流! ----------
第一部分、多态
1、定义
父类引用指向子类对象。列如,动物中有猫和狗,猫和狗都属于动物,可以有
猫 x=new 猫();
同时猫也属于动物,也可以把猫叫做动物,即可以有如下:
动物 y=new 猫();
这里动物是父类,猫和狗是子类,y是父类引用,指向了子类猫new的对象。这里子类可以有两种形态,动物和猫,
即子类既是子类也是父类,这就叫做多态。
2、多态实现的前提
a、类与类之间要有关系,要么是继承,要么实现
b、存在覆盖
3、特点:
a、多态大大提高了程序的扩展性,当时只能使用父类引用访问父类中的成员。
b、多态至始至终都是子类在做着变化:
class Cat extends Animal{//子类
public void eat(){//覆盖父类的eat方法
System.out.println("Cat eat!");
}
public void catchMouse(){//子类特有的方法
System.out.println("Cat catch Mouse!!");
}
}
class Animal{//父类
public void eat(){
System.out.println("Animal eat!");
}
}
class Test{
public static void main(String[] args){
Animal a=new Cat();//父类引用指向子类对象
a.eat();//调用父类中存在的被子类覆盖了的方法
Cat c=(Cat)a;//想调用子类中的方法,需要将其转型
c.catchMouse();//调用子类的方法
}
}
c、多态中成员函数的特点
A、在编译时期:(Fu f=new Zi();)
参阅引用型变量(父类)所属的类中是否有调用的方法。如果有,编译通过,反之不同过。
B、在运行时期:
参阅对象所属的类型(子类)中是否有调用方法。
简单总结:成员函数在多态调用时,编译看左边(父类中是否有该调用方法),运行看右边(子父类中都有,f.method()但调用的是子类中的方法)
C、在多态中,静态成员函数的特点:无论编译和运行,都参考左边。
d、在多态中,成员变量的特点:
无论编译还是运行,都参考左边(引用型变量所属的类)
public class forxuhuan {
public static void main(String[] args) {
Fu f=new Zi();
f.method1();//Zi :method1调用看子类,子类中覆盖了父类,调用子类
f.method2();//Fu :method2子类中没有,父类中有,调用父类
//f.method3();父类中没有不能调用,编译看父类,父类中有才能编译通过
}
}
class Fu{
public void method1(){
System.out.println("Fu :method1");
}
public void method2(){
System.out.println("Fu :method2");
}
}
class Zi extends Fu{
public void method1(){
System.out.println("Zi :method1");
}
public void method3(){
System.out.println("Zi :method3");
}
}
第二部分、内部类
1、定义:
将一个类定义在另一个类的里面,对里面那个 类就称为内部类(内置类,嵌套类)。
2、访问特点:
a、内部类可以直接访问外部类中的成员,包括私有成员,因为内部类中持有一个外部类的引用。
格式:
外部类名.this
b、而外部类要访问内部类中的成员必须要建立内部类的对象。
3、内部类定义的位子
A、内部类定义在成员位置上
- 可以被private 、static成员修饰符修饰。
- 被static修饰的内部类只能访问外部类中的静态成员。
B、内部类定义在局部位置上
- 也可以直接访问外部类中的成员。
- 同时可以访问所在局部中的局部变量,但必须是被final修饰的。
4、成员内部类的访问:
方法的访问:
当内部类定义在外部类的成员位子,并且非私有时:
A、内部类、和内部类的方法均为非静态时,对内对象访问格式下:
外部类名.内部类名 变量名=外部类对象.内部类对象
Outer.Inner in=new Outer().new Inner();
B、当内部类被static修饰后,其只能访问外部类中的static成员,访问出现了局限性。
在外部类中访问静态内部类的非静态成员方法格式如下:
Outer.Inner in=new Outer.Inner().function();
在外部类中访问静态内部类的静态成员方法格式如下:
Outer.Inner.function();
C、当内部类中定义了静态成员,该内部类必须是static的。
当外部类中的静态方法访问内部类,内部类也必须是静态的。
变量的访问:
class Outer{
private int x=2;//外部类成员变量
class Inner{
private int x=3;//内部类成员变量
public void function(){
int x=4;//内部类局部变量
System.out.println(Outer.this.x);//2,访问外部类的成员变量
System.out.println(this.x);//3,访问本类的成员变量
System.out.println(x);//4,访问方法中的局部变量
}
}
public void method(){
Inner in=new Inner();
in.function();
}
}
class Test{
public static void main(String[] args){
Outer.Inner in=new Outer().new Inner();//外部类和内部类都是非静态的
in.function();
}
}
5、局部内部类的访问
A、 局部内部类、局部内部类的方法不能为静态
B、局部内部类不能被成员修饰符修饰
C、可以直接访问外部类的成员,因为还持有外部类的引用,但是,只能访问他所在的局部中被fianl修饰的局部变量,因为这个是为了避免在内部类析构时,他的局部变量被释放,定义为fianl,相当于为他析构准备一个副本。
class Outer{
private int x=2;//外部类成员变量
public void method(){
int y=3;
class Inner{
private int x=4;
public void function(){
int x=5;
System.out.println(Outer.this.x);//2,访问外部类成员变量
System.out.println(y);//3,访问局部中的局部变量,以前版本必须是fianl
System.out.println(this.x);//4,访问内部类成员变量
System.out.println(x);//5,访问内部类的局部变量
}
}
Inner in=new Inner();//建立内部类对象,方便调用
in.function();
}
}
class Test{
public static void main(String[] args){
Outer in=new Outer();
in.method();
}
}
6、匿名内部类
A、匿名内部类其实就是内部类的简写格式,即为一个匿名的子类对象。
B、匿名内部类的前提:内部类必须继承一个类或者实现一个接口
C、匿名内部类的格式:
new 要继承的父类或者要实现的接口名(){定义子类的内容,复写实现的接口的抽象方法}
//定义一个接口
interface Function{
void method();//抽象方法
}
//定义一个子类实现接口方法
class Inter implements Function{
public void method(){//复写抽象方法
System.out.println("interface: implements print");
}
}
//定义一个父类
class Fu{
public void method(){
System.out.println("extends: fu lei");
}
}
//定义一个子类继承父类
class Zi extends Fu{
public void method(){
System.out.println("extends: zi lei fu xie");
}
}
class Test{
public static void main(String[] args){
//1、使用匿名内部类实现接口对象
new Function(){
public void method(){//复写抽象方法
System.out.println("interface:ni ming print");
}
}.method();//调用实现的方法
//2、通过子类实现接口,建立对象调用
Inter in=new Inter();
in.method();
//3、使用匿名内部类实现继承类的子类对象
new Fu(){
public void method(){
System.out.println("extends:ni ming print");
}
}.method();
//4、建立子类对象调用方法
Zi zi=new Zi();
zi.method();
}
}