抽象:
在深入了解多态,之前我们先来了解一下什么是抽象类和抽象方法:
抽象类和抽象方法:抽象方法就是说用abstract关键词修饰的只有方法声明没有具体实现的方法比如:
public abstract void test();
假设我们要写一个动物类,而动物类下方有许多下层类,他们其中大多数的行为属性斗鱼动物类重复,但是在具体到对象个体实施的时候又有个体上的区别,所以这个时候在上层动物类实现这些功能就没有必要了,但是设计程序的时候应该在上层定义这些类型应该有什么功能,然后让子类继承父类,在子类中对抽象方法进行重写。
抽象类:被abstract关键字修饰的类,里面可能会包含抽象的方法,当类中没有足够的信息来描述一个具体的对象(即就是有抽象的方法)时,声明其为一个抽象的类,抽象类无法创造对象。抽象类除了不能创建对象之外,其他功能都正常,静态方法不能被修饰为抽象方法。
public abstract class attack {
//创建一个抽象类
String method;
public attack(){
}
public attack(String method){
this.method=method;
}
//抽象类中的抽象方法,我们在调用抽象方法的时候需要在子类中对其进行重写
public abstract void fight();
public abstract void elude();
public abstract void defense();
}
public class punch extends attack {
public punch(String method){
this.method=method;
}
//子类中对于抽象方法的重写
@Override
public void fight() {
System.out.println("使用"+method+"攻击");
}
@Override
public void defense() {
System.out.println("使用"+method+"防御");
}
@Override
public void elude() {
System.out.println("使用"+method+"躲避");
}
}
public class test {
public static void main(String[] args) {
//对于调用子类中重写过的方法
new punch("拳头").fight();
new punch("拳头").elude();
new punch("拳头").defense();
}
}
多态:
多态时在父类引用指向子类对象从而产生的多种形态:
Animal dog = new Dog();
Animal cat = new Cat();
如上:同一种事物在不同时刻表现不同状态,即就是多态。
关于多态这种方式的优点我们给出代码通过实例来看会更加方便
public abstract class Hero {
String name;
public Hero(){
}
public Hero(String name){
}
public abstract void heroRun();
public void heroAttack(){
System.out.println(this.name+"攻击");
}
public static void sitDown(){
System.out.println("坐下");
}
}
public class Cui extends Hero{
@Override
public void heroRun() {
this.name="Cui";
System.out.println(name+"起飞");
}
}
public class Aoz extends Hero{
@Override
public void heroRun() {
this.name="Aoz";
System.out.println(name+"用嘴爬");
}
@Override
public void heroAttack() {
System.out.println(this.name+"用法杖敲");
}
public static void sitDown(){
System.out.println("蹲凳子上");
}
public void skill(){
System.out.println("雷击");
}
}
public class Enemy {
public void meetHero(Hero hero){
hero.heroRun();
}
}
public class test {
public static void main(String[] args) {
//如果没有通过抽象类实现,那么每一次调用都需要new一个对象出来
//如果每次都要new一个对象,在后期对功能进行修改、维护的时候就不方便了
//注意调用的时候,分为编译期间和运行期间
//编译期间,因为类型上升为了父类类型,所以只能调用到父类中定义的成员
//编译看左边,运行看右边
Hero Aoz=new Aoz();
Hero Cui=new Cui();
new Enemy().meetHero(Aoz);
new Enemy().meetHero(Cui);
//如果子类没有重写父类方法,则调用还是父类方法:
Aoz.heroAttack();
Cui.heroAttack();
//对于静态方法而言都调用左边类型的方法,
Aoz.sitDown();
Hero.sitDown();
//向下类型转换
Aoz=(Aoz)Aoz;
((Aoz) Aoz).skill();
}
}
关于上述代码我还要在这里讲一下:向下取类
当我们将类型上升为父类类型之后,就无法调用到子类中特有的方法,解决办法便是向下取整,将父类类型强制转换为子类类型。但我们这里需要注意的是转换的类之间需要有继承关系,否则无法继承。(这里我们可以通过instanceof 函数来判断实际运行时的类型是否一致)
final关键字
final关键字很像我们在C语言中学过的const这个关键字一样:用于修饰类方法、参数和属性
修饰之后:类:不能被定义为抽象类或是接口,不可被继承
方法:子类里不可以重写
参数:参数值在方法中不可被修改
属性:定义是就必须直接赋值或者在构造方法中进行复制,并且后期不能进行修改
public final class finalTest {
//final定义的类不能定义抽象类也不可被继承
//当每次创建只调用一次的时候,我们可以直接将他定义成一个静态变量
static int num;
//在某些时候要对常量初始化赋值的时候我们也可以将其定义为final类型的值
final int count;
public finalTest(int count){
//属性子啊定义的时候就必须直接赋值或者在构造方法中进行赋值,而且后期不能进行修改
this.count=count;
}
public final void test(final int a){
//不可以被重写,参数值在方法中不可以被修改
//int a
}
}
接口
这里我们简单了解一些关于接口的概念,下一次再深入学习接口:
USB接口本身没有实现任何功能,USB接口规定了数据传输的要求,USB接口可以被多种USB设备实现(编写USB接口,实现USB接口,使用USB接口)
面向接口编程:关心能力而不关心细节,面向接口的约定而不考虑接口的具体实现(接口是一种特殊的抽象类,这种抽象类中包含抽象方法)
接口的修饰词为:interface
public interface MyInterface{
//静态常量
int num=10;
public void foo(){//其中public是默认写好的可以不用输入
//抽象方法
}
public static void test(){//其中public static是默认写好的可以不用输入
//静态方法
}
public default void test1(){//其中public default是默认写好的可以不用输入
//默认方法
}
}
接口是一种更为彻底的抽象,主要用来定义功能,接口不能被创建对象连构造方法都没有。如上所见四种定义:其中最后两种静态方法和默认方法是jdk8版本之后新增的定义。并且一个类可以实现多个接口。