一:多态的概念
(1)多态是面向对象的第三个特征。
(2)多态就是指允许不同类的对象对同一个消息做出响应,即同一消息可以根据发送对象的不同采用多种行为方式。
(3)java引用变量有两个类型:一个是编译时类型,一个是运行时类型,编译时类型由声明给引用变量的类型多决定,运行时变量由实际变量赋值创建的对象所决定。
如果编译时类型和运行时类型不一致,会有可能出现所谓的多态。
例如:
Animal a=new Fish();
//Fish类是Animal类的子类,编译时类型是Animal类,运行时类型是Fish类
二:多态的类型
1)向上转型:父类型的变量引用子类型的变量 。
(1)父类型的变量指向不同的子类型对象,真正实现的功能也是不同的。
(2)因为继承关系,不同的父类型变量可以指向同一个对象,并且有不同的功能。
2)向下转型:将父类型(接口)的变量赋值给子类型或者是其他父类型(接口)的变量。
Animal a = new Fish();
Fish f1 =(Fish)a;//强制类型转换
注意:
Cat c=(Cat)a;//编译通过,语法通过,但是运行时会报错,造型错误,(java.lang.ClassCastException ),属于运行时异常,可理解鱼时不能变成狗的。
三:内部类
1)内部类的概念:即外部类(相对于来说)里面还有一个类,为内部类。
2)内部类的划分:
据位置的不同,可以分为:
成员内部类,方法内部类(局部内部类),静态内部类,匿名内部类
(1)方法内部类:定义在方法中,相当于局部变量,仅限在方法内部使用。
PS:定义时不能使用修饰词,可以直接访问外部类的非静态成员变量
package duotai;
//方法内部类的学习
public class InnerClass {
char gender;
public void run() {
class InnerClassB{//定义内部类,不能使用修饰词
String name;
int age;
public InnerClassB(String name,int age) {
this.name=name;
this.age=age;
}
public void showB() {
System.out.println(age+"");
}
}
InnerClassB b=new InnerClassB("fdfs",43);//方法内部直接声明调用
b.showB();
}
public static void main(String[] args) {
InnerClass i=new InnerClass();
i.run();
}
}
(2)静态内部类:顾名思义,以类的成员来定义的,但是多了一个静态修饰词static
可以直接访问外部类的静态成员。
package duotai;
//静态内部类的使用
public class StaInClass {
static String name;
StaInClassB b=new StaInClassB(43);
static class StaInClassB{
int age;
public StaInClassB(int age) {
this.age=age;
}
//静态内部类可以直接访问外部静态成员
public void showB() {}
}
}
内部类和静态内部类属于不常用的是方法。
(3)成员内部类:以类的成员来定义,可以使用任何修饰词来修饰。
访问:
1).成员内部类访问外部类的成员,方法内隐藏一个指向外部类对象的引用。
格式:外部类名.this.
2). 外部类访问成员内部类的成员在外部类添加一个内部类的成员变量进行访问
使用:
要先创建一个外部类的对象outer, 然后使用外部类对象去使用new调用内部类的构造器实例化
Inner i = outer.new Inner(有参传参);
package duotai;
//成员内部类的使用
public class MemInClass {
char gender;
int age;
//添加一个内部类的成员变量
Baby baby;
public MemInClass(char gender,int age) {
this.gender=gender;
this.age=age;
baby=new Baby('c');
}
public void sport() {
System.out.println("正在走路");
/**访问成员变量的信息*/
System.out.println("信息"+baby.toString()+","+baby.gender);
}
class Baby{
char gender;
public Baby(char gender) {
this.gender=gender;
}
public void show() {
System.out.println("妈妈的年龄"+MemInClass.this.age+"我的性别"+gender);
baby.show();
}
}
(4)匿名内部类:
没有名字的类型,写在外部类的方法中,只用一次,不需要定义类的结构,通常都是为了实现接口,抽象类或某一现有的类的子类 , 子类没有名称,所以称之匿名。
package duotai;
//匿名内部类
public class UnnaInClass {
public static void main(String[] args) {
// TODO Auto-generated method stub
//测试接口的子类型
I sub=new I() {
public void show() {
System.out.println("自我展示");
}
};
}
interface I{
public void show();
}
}
Ps:
(1).匿名内部类 不能是抽象类,因为系统在创建匿名内部类时,会立即创建匿名内部类的对象,因此不能将匿名内部类定义成抽象类
(2).匿名内部类不能定义构造器,因为匿名内部类没有类名,所以无法定义构造器