8.Java面向对象-抽象类、接口

8.Java面向对象-抽象类、接口

一、抽象类的概述及其特点

A:抽象类概述
	回想前面我们的猫狗案例,提取出了一个动物类。并且我们在前面也创建过了动物对象,其实这是不对的。
		为什么呢?因为,我说动物,你知道我说的是什么动物吗?只有看到了具体的动物,你才知道,这是什么动物。 
	所以说,动物本身并不是一个具体的事物,而是一个抽象的事物。只有真正的猫,狗才是具体的动物。
	同理,我们也可以推想,不同的动物吃的东西应该是不一样的,所以,我们不应该在动物类中给出具体体现,而是应该给出一个声明即可。
	在Java中,一个没有方法体的方法应该定义为抽象方法,而类中如果有抽象方法,该类必须定义为抽象类。
B:抽象类特点
	a:抽象类和抽象方法必须用abstract关键字修饰
		抽象类格式:		abstract class 类名 {}
		抽象方法格式:	public abstract void eat();
	b:抽象类不一定有抽象方法,有抽象方法的类一定是抽象类
	c:抽象类中可以有构造方法,抽象类不能进行实例化,那么要构造方法有什么作用呢?
		用于子类访问父类数据时的初始化
	d:抽象类不能直接实例化那么,抽象类如何实例化呢?
		按照多态的方式,由具体的子类实例化。其实这也是多态的一种,抽象类多态。
	e:抽象类的子类
		要么是抽象类
		要么重写抽象类中的所有抽象方法
package org.westos.java9;

public abstract class Animal {
    int age;
    String name;
    public abstract void eat();
    public abstract void sleep();
    public void show(){
        System.out.println("animal show");
    }
}

abstract class demo extends Animal{
    public abstract void demo();
}

class demozi extends demo{
    //三个方法都需要重写
    @Override
    public void eat() {

    }

    @Override
    public void sleep() {

    }

    @Override
    public void demo() {

    }
}
class Dog extends Animal{

    @Override
    public void eat() {
        System.out.println("dog eat");
    }

    @Override
    public void sleep() {
        System.out.println("dog sleep");
    }
}
package org.westos.java9;

public class Test {
    public static void main(String[] args) {
        Animal dog=new Dog(); // 多态的方式去接收
        System.out.println(dog.age); // 0
        System.out.println(dog.name); // null
        dog.eat(); // dog eat
        dog.sleep(); // dog sleep
        dog.show(); // animal show
    }
}

二、抽象类的成员特点

A:抽象类的成员特点
	a:成员变量:既可以是变量,也可以是常量。
	b:构造方法:有。
				用于子类访问父类数据的初始化。
	c:成员方法:既可以是抽象的,也可以是非抽象的。
B:案例演示
	抽象类的成员特点
C:抽象类的成员方法特性:
	a:抽象方法 		强制要求子类做的事情。
	b:非抽象方法    子类继承的事情,提高代码复用性。

三、抽象类中的面试题

A:面试题1
	一个类如果没有抽象方法,可不可以定义为抽象类?如果可以,有什么意义?
	答案: 可以 . 不能创建对象.
B:面试题2
	abstract不能和哪些关键字共存?
		private    冲突 (私有不能继承,则不能重写)
		final      冲突 (final修饰类不能被继承,不能继承,也就意味着不能被重写,修饰方法不能被重写)
		static     不能共存 无意义 (static修饰的方法不参与重写)

四、接口的概述及其特点

A:接口概述
	继续回到我们的猫狗案例,我们想想狗一般就是看门,猫一般就是作为宠物了。
	但是,现在有很多的驯养员或者是驯兽师,可以训练出:猫钻火圈,狗跳高,狗做计算等。
	而这些额外的动作,并不是所有猫或者狗一开始就具备的,这应该属于经过特殊的培训训练出来的。
	所以,这些额外的动作定义到动物类中就不合适,也不适合直接定义到猫或者狗中,因为只有部分猫狗具备这些功能。
	所以,为了体现事物功能的扩展性,Java中就提供了接口来定义这些额外功能,并不给出具体实现,将来哪些猫狗需要被培训,只需要这部分猫狗把这些额外功能实现即可
B:接口特点
	a:接口用关键字interface表示		 格式: 	interface 接口名 {}
	b:类实现接口用implements表示	 格式:	class 类名 implements 接口名 {}
	c:接口不能实例化
		那么,接口如何实例化呢?
		按照多态的方式来实例化。
	d:接口的子类
		a:可以是抽象类。但是意义不大。
		b:可以是具体类。要重写接口中的所有抽象方法。(推荐方案)
package org.westos.java9;

//接口
public interface Jump {
    //必须重写
    public abstract void show();

    //可以选择重写或者不重写
    public default void show2(){
        System.out.println("default show2");

    }
    
    //static修饰的方法,不被继承,只能使用类名调用
    public static void show3(){
        System.out.println("static show3");
    }
}
package org.westos.java9;

//抽象类Animal
public abstract class Animal {
    public abstract void eat();
    public abstract void sleep();
}
package org.westos.java9;

//具体类Tiger继承抽象类实现接口
public class Tiger extends Animal implements Jump {
    @Override
    public void eat() {
        System.out.println("tiger eat");
    }

    @Override
    public void sleep() {
        System.out.println("tiger sleep");
    }

    @Override
    public void show() {
        System.out.println("tiger show");
    }
}
package org.westos.java9;

//抽象类AbsTiger继承抽象类实现接口
public abstract class AbsTiger extends Animal implements Jump {
    public abstract void abstiger();
}

//具体类Demo继承抽象类AbsTiger
class Demo extends AbsTiger{
	//重写所有方法(包括抽象类中的抽象方法和接口中的抽象方法)
    @Override
    public void abstiger() {

    }

    @Override
    public void eat() {

    }

    @Override
    public void sleep() {

    }

    @Override
    public void show() {

    }
}
package org.westos.java9;

//测试类
public class Test {
    public static void main(String[] args) {
        Animal tiger1=new Tiger();
        tiger1.sleep(); // tiger sleep
        tiger1.eat(); // tiger eat
        Jump tiger2=new Tiger();
        tiger2.show(); // tiger show
        tiger2.show2(); // default show2
        //tiger2.show3(); //报错
        Jump.show3(); // 类名调用static修饰的方法 static show3
        Tiger tiger = new Tiger();
        tiger.eat(); // tiger eat
        tiger.sleep(); // tiger sleep
        tiger.show(); // tiger show
        tiger.show2(); // default show2
        //tiger.show3() //报错
    }
}

五、接口的成员特点

A:接口成员特点
	成员变量;只能是常量,并且是静态的。
			默认修饰符:public static final
			建议:自己手动给出。
	构造方法:接口没有构造方法。
	成员方法:只能是抽象方法。
			默认修饰符:public abstract
			建议:自己手动给出。
package org.westos.java9;

public interface Jump {
    // int num; 报错
    //private static final int num=5; 报错
    public static final int num=5;
    int a=2; //默认修饰符 public static final
    public abstract void show();
    void show2();//默认修饰符 public abstract
}

六、类与类,类与接口,接口与接口的关系

A:类与类,类与接口,接口与接口的关系
	a:类与类:
		继承关系,只能单继承,可以多层继承。
	b:类与接口:
		实现关系,可以单实现,也可以多实现。
		并且一个类,还可以在继承一个类的同时实现多个接口。
	c:接口与接口:
		继承关系,可以单继承,也可以多继承。
B:案例演示
	类与类,类与接口,接口与接口的关系
package org.westos.java9;

public class Test {
    public static void main(String[] args) {
        Demo zi=new Demo2();
        zi.demoFu1(); //zi1
        zi.demoFu2(); //zi2
        zi.demoZi(); //zizi
    }
}

interface DemoFu1{
    void demoFu1();
}
interface DemoFu2{
    void demoFu2();
}
interface DemoZi extends DemoFu1,DemoFu2{
    void demoZi();
}

class Demo implements DemoFu1,DemoFu2,DemoZi{

// class Demo implements DemoZi{} 也要重写三个方法,因为接口DemoZi继承了DemoFu1和DemoFu2
    @Override
    public void demoFu1() {
        System.out.println("fu1");
    }

    @Override
    public void demoFu2() {
        System.out.println("fu2");
    }

    @Override
    public void demoZi() {
        System.out.println("zi");
    }
}

class Demo2 extends Demo implements DemoFu1,DemoFu2,DemoZi{
   //以下接口中的三个方法不重写也是可以的,因为父类中已经重写过接口的抽象方法。
    @Override
    public void demoFu1() {
        System.out.println("zi1");
    }

    @Override
    public void demoFu2() {
        System.out.println("zi2");
    }

    @Override
    public void demoZi() {
        System.out.println("zizi");
    }
}

七、抽象类和接口的区别

A:成员区别
	抽象类:
		成员变量:可以变量,也可以常量
		构造方法:有
		成员方法:可以抽象,也可以非抽象
	接口:
		成员变量:全部是公共的静态常量 public static final
		成员方法:只可以抽象	JDK1.8之后可以定义 default修饰的方法,可以给出功能的具体实现,子类可以继承下去用,JDK1.8之后在接口中也可以定义静态方法
B:关系区别
	类与类
		继承,单继承
	类与接口
		实现,单实现,多实现
	接口与接口
		继承,单继承,多继承	
C:设计理念区别
	抽象类 	被继承体现的是:”is a”的关系。	抽象类中定义的是该继承体系的共性功能。
	接口 	被实现体现的是:”like a”的关系。	接口中定义的是该继承体系的扩展功能。

注意:JDK1.8之后在接口中提供了用default修饰的方法,可以给出功能的具体实现,子类可以继承下去用
      JDK1.8之后在接口中也可以定义静态方法

八、猫狗案例加入跳高功能分析及其代码实现

package org.westos.java9;

//接口跳高
public interface Jump {
    void show();
}
package org.westos.java9;

//抽象动物类
public abstract class Animal {
    private int age;
    private String name;

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
    public abstract void eat();
    public abstract void sleep();

    public Animal(int age, String name) {
        this.age = age;
        this.name = name;
    }

    public Animal() {
    }
}
package org.westos.java9;

public class Cat extends Animal {
    @Override
    public void eat() {
        System.out.println("cat eat");
    }

    @Override
    public void sleep() {
        System.out.println("cat sleep");
    }

    public Cat(int age, String name) {
        super(age, name);
    }

    public Cat() {
        super();
    }
}
package org.westos.java9;

public class TomCat extends Cat implements Jump{
    @Override
    public void eat() {
        System.out.println("tom eat");
    }

    @Override
    public void sleep() {
        System.out.println("tom sleep");
    }

    @Override
    public void show() {
        System.out.println("tom jump");
    }

    public TomCat(int age, String name) {
        super(age, name);
    }

    public TomCat() {
        super();
    }
}
package org.westos.java9;

public class Test {
    public static void main(String[] args) {
        Animal tom1=new TomCat();
        tom1.eat(); // tom eat
        tom1.sleep(); // tom sleep
        Jump tom2=new TomCat();
        tom2.show(); // tom jump
        TomCat tom3 = new TomCat(5, "tom");
        System.out.println(tom3.getAge()); // 5
        System.out.println(tom3.getName()); // tom
        tom3.eat(); // tom eat
        tom3.sleep(); // tom sleep
        tom3.show(); // tom jump
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值