多态的概念:
同一种事物,在不同时刻表现不同状态。
Animal dog = new Dog();
Animal cat = new Cat();
父类的引用变量指向子类对象
前提 :必须要有继承关系
两个不同时间段
1.编译期:写代码时 类型是父类类型
2.运行期: 运行代码时 类型是具体的子类类型
多态也称为向上转型,将子类转为父类
优点:可以提高程序的延展性
多态时成员方法调用:编译看左边,运行看右边。
多态时静态成员方法调用:编译看左边 运行看左边。
多态时成员变量调用:编译看左边 运行看左边。
public class anlimal {
int num;
public static void show(){
System.out.println("展示");
}
public void eat(){
System.out.println("动物吃东西");
}
}
import oop04.dt.anlimal;
public class Dog extends anlimal {
public void lookhome(){
System.out.println("看家");
}
}
import oop04.dt.anlimal;
public class fish extends anlimal {
@Override
public void eat() {
System.out.println("大鱼吃小鱼");
}
}
import oop04.dt.anlimal;
public class bx {
public void putthing(anlimal anlimal){
System.out.println("放进冰箱");
if(anlimal instanceof Dog){
Dog dog =(Dog)anlimal;
dog.lookhome();
}
}
}
import oop04.dt.Dog;
import oop04.dt.anlimal;
import oop04.dt.bx;
import oop04.dt.fish;
public class test {
public static void main(String[] args) {
anlimal fish =new fish();
anlimal dog=new Dog();
bx bx=new bx();
bx.putthing(fish);
/*
成员方法:编译看左边,运行看右边
*/
fish.eat();
dog.eat();
/*
静态成员方法:编译和运行都看左边
*/
dog.show();
fish.show();
/*
成员变量:编译和运行都看左边
*/
System.out.println(dog.num);
}
}
import oop04.dt.Dog;
import oop04.dt.anlimal;
import oop04.dt.fish;
public class test2 {
public static void main(String[] args) {
anlimal dog=new Dog();
anlimal fish=new fish();
/*
将子类类型都转为父类类型,便于程序的扩展
但是也存在问题:
一旦转为父类类型,就不能调用到子类中特有的方法。
*/
dog.eat();
fish.eat();
}
}
多态问题:
ba子类类型都转换为父类类型,此时,就不能调用到子类中特有的方法
解决办法:将父类类型向下转换为子类类型
转换时需要使用instanceof判断 父类类型持有的对象 是否是指定的子类类型
父类类型instanceof 具体子类类型 --true 否则 --false
if(anlimal instanceof Dog){
Dog dog =(Dog)anlimal;
dog.lookhome();
}
final关键字
final修饰 类,方法,参数,成员变量(常量)
final 修饰的类是不能被继承的,所以不能修饰抽象类,例如java中String类就是有final修饰
final修饰的方法不能被重写
final修饰方法的参数,参数值在方法中不能被改变
final修饰的成员变量值不能改变,因此称为常量
public class finaldemo {
//情况1:在类定义时,值就确定,直接赋值,赋值后值不能改变的,所以建议使用static修饰
final static int a=10;
//情况2:在类定义时,值不能确定,必须在创造对象后,在构造方法对其进行赋值,每个对象中拥有一个常量
final int count;
public finaldemo(){
this.count=10;
}
public finaldemo(int count){
this.count=count;
}
public void test(final int a){
//a=20;
}
public static void main(String[] args) {
finaldemo finaldemo=new finaldemo(10);
finaldemo finaldemo1=new finaldemo(30);
finaldemo.test(10);
finaldemo1.test(20);
}
}
接口
接口是计算机领域的名词,表示一种功能的定义
例如USB接口 定义usb接口的规范,让其他设备去实现
接口可以看作是一种特殊的抽象类,里面也可以包含抽象方法
接口不能被创建对象,被其它类实现,重写抽象方法
主要也是用来定义功能的
• 从本质上讲,接口是一种特殊的抽象类,这种抽象类中包含抽象方法。
接口的定义:使用 interface 关键字用来声明一个接口。
[访问修饰符] interface 接口名称 [extends 其他的接口名1,….其他的接口名n] { // 声明常量 抽象方法 静态方法 默认方法 }
接口的使用:类使用implements关键字实现接口。在类声明中,Implements 关键字放在class声明后面。
[访问修饰符] class 类名 implements 接口名1,接口名2……{ }
结合继承: [访问修饰符] class 类名 extends 父类名 implements 接口名1,接口名2……{ }
public interface interfaceA {
void a();
}
public interface interfaceB {
void b();
void c();
}
public interface interfaceC {
void d();
}
public interface Myinterface {
int num =10;//== public static final int num=10;
void eat();// public abstract void eat();
//静态方法 可以直接通过接口名调用
public static void test(){}
//默认方法,被子类继承后调用的
default void test1(){}
}
public class classdemo extends Object implements Myinterface, interfaceA, interfaceB, interfaceC {
@Override
public void eat() {
System.out.println("chi");
}
@Override
public void a() {
}
@Override
public void b() {
}
@Override
public void c() {
}
@Override
public void d() {
}
/*
类通过implements关键字实现接口
类实现接口后,要么重写接口中的所有抽象方法
要么将该类声明为抽象类
一个类可以直接继承一个类,
一个类可以实现多个接口,
一个接口还可以继承多个接口
*/
}
接口的特性
(1)接口是隐式抽象的,主要用来定义功能.
(2) 接口中可以定义静态常量,抽象方法,静态方法,默认方法.
(3)一个接口能继承其它多个接口. l 接口不能实例化对象.
(4)接口是要被类实现,一个接口可以被多个实现
(5)当类实现接口的时候,类要实现接口中所有的抽象方法,否则,该类必须 声明为抽象的类.
(6)接口与实现类之间存在多态性