多态
前提:要有继承关系
要有方法重写
要有父类引用指向子类对象
多态中成员访问特点:
- 成员变量 : 编译看左边 运行看左边
- 成员方法 :编译看左边 运行看右边
- 静态方法 : 编译看左边 运行看左边(静态和类相关,算不上重写所以访问还是左边的)
只有非静态的成员方法,编译看左边,运行看右边
public class duotai {
public static void main(String[] args) {
// TODO Auto-generated method stub
Father f =new Son();//父类引用指向子类对象
System.out.println(f.num); //输出值10 成员变量: 编译看左边(父类)运行看右边(子类)
Son s =new Son();
System.out.println(s.num);//输出值 20
}
}
class Father{
int num=10;
}
class Son extends Father{
int num =20;
}
原理图:
public class duotai {
public static void main(String[] args) {
// TODO Auto-generated method stub
Father f =new Son();//父类引用指向子类对象
f.print(); //输出值 son 编译看左边,运行看右边(子类) 动态绑定
}
}
class Father{
int num=10;
public void print(){
System.out.println("father");
}
}
class Son extends Father{
int num =20;
public void print(){
System.out.println("son");
}
}
原理图:
public class duotai {
public static void main(String[] args) {
// TODO Auto-generated method stub
Father f =new Son();//父类引用指向子类对象
f.method(); //输出值 Father static method 编译看左边,运行看左边(子类) 动态绑定
}
}
class Father{
int num=10;
public void print(){
System.out.println("father");
}
public static void method(){
System.out.println("Father static method");
}
}
class Son extends Father{
int num =20;
public void print(){
System.out.println("son");
}
public static void method(){
System.out.println("son static method");
}
}
数据类型提升
int i=10;
byte b =20;
i=b;//自动类型提升
b=(byte)i;//强制类型转换
父类引用指向子类对象就是向上转型: Person p =new SuperMan()
向下转型: SuperMan sm=(SuperMan) p
多态优缺
优:提高了代码的维护性(继承保证)
提到了代码的可扩展性(多态保证)
缺: 不能使用子类特有属性和行为
题目分析
public class duotai2 {
public static void main(String[] args) {
// TODO Auto-generated method stub
Fu f=new Zi();
f.method();
f.show();
}
}
class Fu{
public void show(){
System.out.println("fu show");
}
}
class Zi extends Fu {
public void show(){
System.out.println("zi show");
}
public void mehtod(){
System.out.println("zi method");
}
}
f.method() 程序会报错,找不到方法
f.show() 输出 “zi show ” 如果将zi 中show()注释则将调用父类 输出“fu show”
题二:
public class duotai3 {
public static void main(String[] args) {
// TODO Auto-generated method stub
A a =new B();
//a.show(); //输出“爱”
B b =new C();
b.show(); //输出“你”
}
}
class A{
public void show(){
show2();
}
public void show2(){
System.out.println("我");
}
}
class B extends A{
public void show2(){
System.out.println("爱");
}
}
class C extends B{
public void show(){
super.show();
}
public void show2(){
System.out.println("你");
}
}
抽象类
1 抽象类特点:
抽象类和抽象方法必须用abstract修饰,
abstract class 类名{}
public abstract void eat();
抽象类不一定有抽象方法,有抽象方法的类一定是抽象类或者接口
抽象类不能实例化,所以,由具体的子类实例化。
抽象类的子类:要么是抽象类要么重写抽象类的所有抽象方法
2 抽象的成员特点
成员变量:既可以是变量,也可以是常量。
abstract是否可以修饰成员变量? : 不能修饰成员变量
构造方法:有 用于子类访问父类数据的初始化
成员方法:既可以是抽象的,也可以是非抽象的
抽象类的成员方法特性:
a :抽象方法 强制要求子类做的事情
b :非抽象方法 子类继承的事情,提高代码复用性。
接口
- 接口特点 :
- [ ]接口用关键字interface 表示 :interface 接口名{}
- 类实现接口用implements
- 接口用多态的方式实现实例化
- 接口的子类可以是抽象类也可以是具体类
- 接口成员特点:
-
成员变量:只能是常量并且是静态的公共的
默认修饰符:public static final -
构造方法: 接口没有构造方法
-
成员方法:只能是抽象方法,默认修饰符 public abstract
- 类与类 类与接口 接口与接口的关系
- 类与类:继承关系,只能单继承,可以多层继承
- 类与接口:可以单实现,可以多实现 可以在继承一个类的同时实现多个接口
- 接口与接口:可以单继承,可以多继承
- 抽象类与接口的区别
- 成员区别:
- 1 抽象类:成员变量可以是变量 可以是常量 ,构造方法有,成员方法可以抽象可以非抽象
- 2 接口:成员变量只能是常量,成员方法只能是抽象
- 关系区别
- [ 1] 类与类 :继承,单继承
- 2 类与接口:实现 单实现,多实现
- 3 接口与接口:继承,单继承,多继承
- 设计理念区别
-抽象类 被继承体现的是“is a”的关系,定义的是该继承体系的共性功能
接口 被实现体系的是“like a”的关系 ,定义的是该继承体系的扩展功能
- 匿名内部类: new 类名或接口名 (){ 重写方法;} 只针对重写一个方法,不能向下转型 因为没有子类类名
匿名内部类当做参数传递(本质吧匿名内部类看做一个对象)