14 面对对象(多态;抽象类;接口)
文章目录
- 多态(动态绑定机制)
- 多态的概述
- 多态的成员访问特点
- 多态的好处和弊端
- 向上转型和向下转型
- 多态内存图
- 猫狗案例多态版
- 多态中的题目分析题
- 抽象类
- 抽象类的概述
- 抽象类的成员特点
- 抽象类的案例
- 接口
- 接口的概述
- 接口的成员特点
- 类与类,类与接口,接口与接口的关系
- 抽象类与接口的区别
- 接口的案例
- 回顾
package org.westos.demo;public final class 回顾 extends Object{public static void main(String[] args) {/** 继承:将多个子类的共性内容,向上抽象到父类中,以实现代码的复用性和维护性,* 继承的弊端:让类跟类产生了关系,增加了耦合性。* 继承注意的事项:* 1.Java中只支持单继承,但是支持多层继承* 2.父类私有的成员,子类不能继承* 3,构造方法不参与继承* 4.不要为了继承而继承。** Object 类是所有类的顶层父类,所有类都是直接或间接继承自他** 方法重写,:因为所有的子类,他继承了父类的功能,那如果说,某个子类,对继承下来的功能实现不满意。* 子类如果不满意父类的功能,就可以覆盖,覆盖之后,就以子类覆盖过后的为准* 重写的注意事项:* 父类的私有功能不能重写* 静态方法不参与重写* 重写时子类方法的权限修饰符,要比父类的高,或者一样* 父类final修饰的方法,也不能重写* 我们在初始化子类时,要先初始父类的数据 super()* super 代表父类空间的一个标识* this 代表本类的一个引用,谁调用方法,方法中的this就代表谁** final 修饰 变量,成员方法,类* */}
}
class A extends Object{//Object 类是所有类的顶层父类,所有类都是直接或间接继承自他
}
class B extends A{}
多态(动态绑定机制)
多态的概述
- 多态概述
某一个事物,在不同时刻表现出来的不同状态。
举例: Cat c=new Cat();
Animal a=new Cat();
猫可以是猫的类型。猫 m = new 猫();
同时猫也是动物的一种,也可以把猫称为动物。动物 d = new 猫(); - 多态前提
a:要有继承关系。
b:要有方法重写。 其实没有也是可以的,但是如果没有这个就没有意义。
c:要有父类引用指向子类对象。
父 f = new 子();
package org.westos.demo;
public class Animal {public void eat() {System.out.println("吃饭");}
}
//------------------------------------------------------------------------
public class Cat extends Animal{@Overridepublic void eat() {System.out.println("猫爱吃鱼");}public void catchMouse(){System.out.println("抓老鼠");}
}//------------------------------------------------------------------------
public class Dog extends Animal{@Overridepublic void eat() {System.out.println("狗吃骨头");}public void lookDoor(){System.out.println("看门");}
}
package org.westos.demo;
public class MyDemo {public static void main(String[] args) {/** 多态:指的是一种事物在不同时刻,所表现出的不同的状态* 猫 是一只猫* 猫 是一种动物* 用这两种状态描述猫都没有问题* Cat cat=new Cat(); 用Cat接受* Animal an=new Cat(); 用Animal接受* 多态的前提:* 1.要有继承关系,如果没有继承关系,那么多态就无从谈起。* 2.要有方法重写,如果没有方法重写,语法上不报错,但是多态就没有意义* 3.父类引用指向子类对象。* *///之前的方式Cat cat = new Cat();cat.eat();//猫爱吃鱼cat.catchMouse();//抓老鼠System.out.println("------------------------");//多态的方式Animal an= new Cat();//用Animal接受Catan.eat();//猫爱吃鱼//如果采用了多态的这种方式,子类重写了父类的方法,那么我在用父类引用调用方法时,会以子类重写过后的为准System.out.println("-------------------");Dog dog = new Dog();//以前的dog.eat();//狗吃骨头dog.lookDoor();//看门System.out.println("--------------------");Animal an2=new Dog();//多态的an2.eat();//狗吃骨头}
}
package org.westos.demo;public class Animal {public void eat() {System.out.println("吃饭");}
}
//------------------------------------------------------------------------
public class Cat extends Animal{public void eat(){System.out.println("猫吃鱼");};
}
//------------------------------------------------------------------------
public class Dog extends Animal{public void eat() {System.out.println("狗吃骨头");}
}
//------------------------------------------------------------------------
public class Tiger extends Animal{@Overridepublic void eat() {System.out.println("老虎吃鸡");}
}
//------------------------------------------------------------------------
public class Fox extends Animal{@Overridepublic void eat() {System.out.println("狐狸吃松鼠");}
}
package org.westos.demo;
public class MyUtils { //把MyUtils作为一个工具类private MyUtils() { //私有化构造 工具类一般让用户直接调}public static void setAnimal(Animal an) { //改成(Animal an)父类类型Animal 就可以接受所有的之类的类型an.eat();}/* public static void setAnimal(Dog dog) {dog.eat();}public static void setAnimal(Cat cat) {cat.eat();}public static void setAnimal(Tiger tiger) {tiger.eat();} */
}
package org.westos.demo;
public class MyDemo {public static void main(String[] args) {/** 多态的优点:* 1.提高代码的维护性 由继承来保证* 2.多态提高了代码的扩展性** 多态的不足:不能直接调用子类特有的功能* */Dog dog = new Dog();MyUtils.setAnimal(dog);// Animal an=new Dog(),之后an.eat()调用的是子类Dog重写后的Cat cat = new Cat();MyUtils.setAnimal(cat);Tiger tiger = new Tiger();MyUtils.setAnimal(tiger);Fox fox = new Fox();MyUtils.setAnimal(fox);}/* public static void setAnimal(Animal an) {an.eat();} */
}
多态的成员访问特点
- 多态中的成员访问特点
a:成员变量
编译看左边,运行看左边。
b:构造方法
创建子类对象的时候,会访问父类的构造方法,对父类的数据进行初始化。
c:成员方法
编译看左边,运行看右边。
d:静态方法
编译看左边,运行看左边。
(静态和类相关,算不上重写,所以,访问还是左边的)
package org.westos.demo;
public class MyTest {public static void main(String[] args) {//Zi zi = new Zi();//System.out.println(zi.num);//100//多态//多态的形式去访问成员变量,访问的还是父类的成员变量//多态访问成员变量:编译看左边,运行看左边。Fu fu=new Zi();System.out.println(fu.num);//10 //用父类引用调父类变量//多态的形式去调用方法时,编译看左边,运行看右边 //编译看左边即父类里面有没有这个方法 运行看右边即子类有没有重写过fu.show();//方法重写后 调的是子类重写后的方法 如果没有重写就调父类的//调用静态方法,运行的是父类的静态方法 //静态方法不算重写fu.test(); }
}
//------------------------------------------------------------------------
class Fu{int num=10;public Fu() {System.out.println("父类构造执行了");}public void show(){System.out.println("fu show");}public static void test() {System.out.println("fu test");}
}
//------------------------------------------------------------------------
class Zi extends Fu{int num=100;public Zi() {System.out.println("子类构造执行了");}@Overridepublic void show() {System.out.println("zi show");}public static void test() {System.out.println("zi test");}
}
多态的好处和弊端
- 多态的好处
a:提高了代码的维护性(继承保证)
b:提高了代码的扩展性(由多态保证) - 多态的弊端
不能直接调用子类特有的功能
向上转型和向下转型
- 通过多态的弊端引出问题
不能使用子类特有的功能 - 解决问题
把父类的引用强制转换为子类的引用。(向下转型)
package org.westos.demo;public class Animal {public void eat(){System.out.println("吃饭");}
}
//------------------------------------------------------------------------
public class Cat extends Animal{@Overridepublic void eat() {System.out.println("猫吃鱼");}public void catcheMouse(){System.out.println("猫抓老鼠");}
}
//------------------------------------------------------------------------
public class Dog extends Animal{@Overridepublic void eat() {System.out.println("狗吃骨头");}public void lookDoor(){System.out.println("狗看门");}
}
package org.westos.demo;
public class MyTest {public static void main(String[] args) {Cat cat = new Cat();cat.eat();cat.catcheMouse();System.out.println("----------------------------");//多态的形式Animal an = new Cat(); //多态就是向上转型 //将子类类型Cat用父类an输an.eat();//多态的弊端,不能访问子类特有的功能// an.catcheMouse(); 会报错 这是多态的弊端 父类引用an调不到子类Cat特有的功能Cat cat= (Cat) an; //将父引用an转成所指的子类型Cat 再用cat去调//向下转型 将父引用转成他所指向的那个子类型 cat.catcheMouse();System.out.println("------------------");Dog dog = new Dog();dog.eat();dog.lookDoor();System.out.println("----------------------------");Animal an2= new Dog();an2.eat();Dog d= (Dog) an2; //向下转型d.lookDoor();}
}
package org.westos.demo;
public class MyTest {public static void main(String[] args) {Animal an = new Dog();an.eat();// an.lookDoor(); //Dog特有方法不能直接用an来调 需要向下转型Dog d= (Dog) an;d.lookDoor();// an=new Cat();Cat cat = (Cat) an;//在这一行会报错:ClassCastException 类型转换异常
//Animal an = new Dog():new了一个Dog对象 在栈内存中存在引用an an指向这个Dog对象
//可以Dog d= (Dog) an将an转成Dog(向下转型就是将父类型转向它指向的那个类型);现在an指向Dog,不能把Dog强转成Cat//如果 Cat cat = (Cat) an 前面加一行" an=new Cat() " 就不报错,将an指向Cat,再将an转型为Catcat.catcheMouse();}
}
package org.westos.demo;
public class MyTest {public static void main(String[] args) {/** 听说孔子爹JavaSE讲的很好,张三慕名前来,把孔子爹请到家里去给他讲课去了* 那么这个时候,李四也来到孔子家里,请孔子爹讲JavaSE 孔子一看学员来了,孔子爹又不在家,* 孔子又不想失去这个学员,孔子经过乔装打扮,装成他爹的样子,给李四讲课,他只会讲论语,* 讲完之后,把李四打发走了,孔子想玩游戏了,卸下这套装扮,去开心的玩游戏去了* */孔子爹 k爹 = new 孔子(); //多态:向上转型 //孔子要装成孔子爹的模样 即向上转型System.out.println(k爹.age); //外在表现 age 60k爹.teache();孔子 k = (孔子) k爹; //向下转型 //孔子想玩游戏了,卸下这套装扮 即向下转型System.out.println(k.age); //外在表现 age 30k.playGame(); //向下转型后就可以 调用自己特有的方法}
}
//------------------------------------------------------------------------
class 孔子爹 {int age = 60;public void teache() {System.out.println("讲授JavaSE");}
}
//------------------------------------------------------------------------
class 孔子 extends 孔子爹 {int age = 30;public void teache() {System.out.println("讲授论语");}public void playGame() {System.out.println("玩游戏");}
}
多态内存图
- 画图演示: 多态的内存图解
package org.westos.demo;
public class MyTest {public static void main(String[] args) {Father fu = new Son();System.out.println(fu.num);//100fu.show();//zi Show //当子类中重写了父类方法后 用多态的形式去调 还是以子类重写过后的为准Son son = (Son) fu;System.out.println(son.num);//19son.method();//子类特有的方法}
}
//------------------------------------------------------------------------
class Father {int num = 100;public void show() {System.out.println("fu show");}
}
//------------------------------------------------------------------------
class Son extends Father {int num = 19;@Overridepublic void show() {System.out.println("zi Show");}public void method() {System.out.println("子类特有的方法");}
}
- 其他举例
猫狗案例多态版
案例演示: 猫狗案例多态版
package org.westos.demo;public class Animal {public String name;public int age;public void eat(){System.out.println("吃饭");};
}
//------------------------------------------------------------------------
public class Cat extends Animal{@Overridepublic void eat() {System.out.println("猫吃鱼");}public void catchMouse(){System.out.println("抓老鼠");}
}
//------------------------------------------------------------------------
public class Dog extends Animal{@Overridepublic void eat() {System.out.println("狗吃骨头");}public void lookDoor(){System.out.println("狗看门");}
}
package org.westos.demo;
public class MyTest {public static void main(String[] args) {Cat cat = new Cat();Animal an=cat;an.name="汤姆";an.age=2;System.out.println(an.name+"==="+an.age);an.eat();Cat cat1= (Cat) an;cat1.catchMouse();System.out.println("----------------------------");an=new Dog();an.name="旺财";an.age=10;System.out.println(an.name + "===" + an.age);an.eat();Dog dog= (Dog) an;dog.lookDoor();}
}
多态中的题目分析题
看下面程序是否有问题,如果没有,说出结果
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("你");}
}public class DuoTaiTest {public static void main(String[] args) {A a = new B();a.show(); //爱B b = new C();b.show(); //你}
}
抽象类
抽象类的概述
- 抽象类概述
回想前面我们的猫狗案例,提取出了一个动物类。并且我们在前面也创建过了动物对象,其实这是不对的。
为什么呢?因为,我说动物,你知道我说的是什么动物吗?只有看到了具体的动物,你才知道,这是什么动物。
所以说,动物本身并不是一个具体的事物,而是一个抽象的事物。只有真正的猫,狗才是具体的动物。
同理,我们也可以推想,不同的动物吃的东西应该是不一样的,所以,我们不应该在动物类中给出具体体现,而是应该给出一个声明即可。
在Java中,一个没有方法体的方法应该定义为抽象方法,而类中如果有抽象方法,该类必须定义为抽象类。 - 抽象类特点
a:抽象类和抽象方法必须用abstract关键字修饰
抽象类格式: abstract class 类名 {}
抽象方法格式: public abstract void eat();
b:抽象类不一定有抽象方法,有抽象方法的类一定是抽象类
c:抽象类中可以有构造方法,抽象类不能进行实例化,那么要构造方法有什么作用呢?
用于子类访问父类数据时的初始化
d:抽象类不能直接实例化那么,抽象类如何实例化呢?
按照多态的方式,由具体的子类实例化。其实这也是多态的一种,抽象类多态。
e:抽象类的子类
要么是抽象类
要么重写抽象类中的所有抽象方法
package org.westos.demo;public abstract class Animal {//abstract 抽象的,可以修饰方法,修饰类//抽象方法:没有方法体的方法 //当你一个类中,有了抽象,此类也必须为抽象类//一个抽象类中可以没有抽象方法,但是一个类中有了抽象方法,此类必须为抽象类
//(肯定知道子类要吃饭睡觉 至于怎么吃怎么睡就是子类的事情 抽象类中的抽象方法强制子类必须重写)
//(父类没有必要给出这类功能的具体实现 等子类继承后 你想怎么吃就怎么吃 想怎么睡就怎么睡 子类自己给出具体功能的重写)public Animal() {System.out.println("Animal 的构造方法");}public abstract void eat();public abstract void sleep();public void show(){System.out.println("fu show");}
}
//------------------------------------------------------------------------
public class Dog extends Animal {public Dog() {System.out.println("Dog 的构造方法");}
//当一个类,继承了一个抽象类,那么这个抽象类中的所有抽象方法,子类必须重写@Overridepublic void eat() {System.out.println("狗吃骨头");}@Overridepublic void sleep() {System.out.println("狗趴着睡觉");}
}
//------------------------------------------------------------------------
public class Cat extends Animal{@Overridepublic void eat() {System.out.println("猫吃鱼");}@Overridepublic void sleep() {System.out.println("猫白天睡觉");}
}
package org.westos.demo;
public class MyTest {public static void main(String[] args) {//1.抽象类,不能直接实例化//2.我们可以采用多态的形式,间接实例化Animal an = new Cat(); //采用多态的形式去new的时候 肯定要初始化父类 父类的构造方法先执行 //(抽象类中构造方法:用于子类访问父类数据时的初始化)an.eat();an.sleep();an = new Dog();an.eat();an.sleep();}
}
package org.westos.demo;public class MyTest {public static void main(String[] args) {}
}
//------------------------------------------------------------------------
abstract class Fu{public abstract void test();
}
//------------------------------------------------------------------------
abstract class Zi extends Fu{ //父类是抽象类 子类要么把自己变成抽象类 要么重写父类中的所有抽象方法public abstract void aa();
}
//------------------------------------------------------------------------
class C extends Zi{ //爸爸Zi和爷爷Fu里面的抽象方法都要继承 @Overridepublic void test() {}@Overridepublic void aa() {}
}
抽象类的成员特点
- 抽象类的成员特点
a:成员变量:既可以是变量,也可以是常量。
b:构造方法:有。
用于子类访问父类数据的初始化。
c:成员方法:既可以是抽象的,也可以是非抽象的。 - 案例演示
抽象类的成员特点 - 抽象类的成员方法特性:
a:抽象方法 强制要求子类做的事情。
b:非抽象方法 子类继承的事情,提高代码复用性。
package org.westos.demo;
public class MyTest {public static void main(String[] args) {//抽象类中,成员变量的特点 抽象类中既可以定义变量,也可以定义常量//抽象类中有构造方法,作用:在创建子类对象时,对父类数据进行初始化//抽象类中,可以有抽象方法,也可以有非抽象方法//抽象方法,强制子类必须重写//非抽象方法,是想让子类继承下去用}
}
abstract class AA{int num=100;public final int a = 10;public void aa(){};public abstract void bb();
}
抽象类的案例
- 抽象类练习猫狗案例
案例演示
具体事物:猫,狗
共性:姓名,年龄,吃饭
package org.westos.demo;public abstract class Aniaml {public String name;public int age;public abstract void eat();
}
//------------------------------------------------------------------------
public class Cat extends Aniaml {@Overridepublic void eat() {System.out.println("猫吃鱼");}public void catchMouse(){System.out.println("猫抓老鼠");}
}
//------------------------------------------------------------------------
public class Dog extends Aniaml{@Overridepublic void eat() {System.out.println("狗吃骨头");}public void lookDoor(){System.out.println("狗看门");}
}
package org.westos.demo;public class MyTest {public static void main(String[] args) {//案例演示//具体事物:猫,狗//共性:姓名,年龄,吃饭Aniaml an = new Cat();an.name="汤姆";an.age=2;System.out.println(an.name+"==="+an.age);an.eat();((Cat) an).catchMouse();an=new Dog();an.name="旺财";an.age=9;System.out.println(an.name+"=="+an.age);an.eat();((Dog) an).lookDoor();}
}
- 抽象类练习员工案例
A:案例演示
假如我们在开发一个系统时需要对员工(Employee)类进行设计,员工包含3个属性:姓名、工号以及工资(salary)。
经理(Manager)也是员工,除了含有员工的属性外,另为还有一个奖金(bonus)属性。
然后定义工作的方法.
请使用继承的思想设计出员工类和经理类。
package org.westos.demo;public class MyTest {public static void main(String[] args) {Person p=new Employee();p.name="张三";p.id=1;p.sal=3000;System.out.println(p.name+"==="+p.id+"==="+p.sal);p.work();p=new Manager();p.name="李四";p.id=2;p.sal=50000;Manager m= (Manager) p;//向下转型m.bonus=1000;p.work();System.out.println(p.name+"==="+p.id+"==="+p.sal+"=="+m.bonus);//一个类如果没有抽象方法,可不可以定义为抽象类 ? 如果可以,有什么意义 ?//可以,外界就不能创建该类的对象// abstract 不能和哪些关键字共存:// private 矛盾(私有的方法都不能被继承 何谈重写) // final 矛盾(final不让重写 abstract强制重写) // static 没有意义(静态的抽象方法 不能共存 没有意义)}
}
//------------------------------------------------------------------------
abstract class Person {int id;String name;double sal;public abstract void work(); //都要工作 但是工作的内容不一样 所以将工作变为抽象方法//public abstract void show();
}
//------------------------------------------------------------------------
class Employee extends Person {@Overridepublic void work() {System.out.println("做一些一线的工作");}
}
//------------------------------------------------------------------------
class Manager extends Person {double bonus;@Overridepublic void work() {System.out.println("做管理的工作");}
}
- 抽象类中的面试题
A:面试题1
一个类如果没有抽象方法,可不可以定义为抽象类?如果可以,有什么意义?
答案: 可以 . 不能创建对象.
B:面试题2
abstract不能和哪些关键字共存?
private 冲突
final 冲突
static 不能共存 无意义
接口
接口的概述
- 接口概述
继续回到我们的猫狗案例,我们想想狗一般就是看门,猫一般就是作为宠物了。
但是,现在有很多的驯养员或者是驯兽师,可以训练出:猫钻火圈,狗跳高,狗做计算等。
而这些额外的动作,并不是所有猫或者狗一开始就具备的,这应该属于经过特殊的培训训练出来的。
所以,这些额外的动作定义到动物类中就不合适,也不适合直接定义到猫或者狗中,因为只有部分猫狗具备这些功能。
所以,为了体现事物功能的扩展性,Java中就提供了接口来定义这些额外功能,并不给出具体实现,将来哪些猫狗需要被培训,只需要这部分猫狗把这些额外功能实现即可 - 接口特点
a:接口用关键字interface表示 格式: interface 接口名 {}
b:类实现接口用implements表示 格式: class 类名 implements 接口名 {}
c:接口不能实例化
那么,接口如何实例化呢?
按照多态的方式来实例化。
d:接口的子类
a:可以是抽象类。但是意义不大。
b:可以是具体类。要重写接口中的所有抽象方法。(推荐方案)
package org.westos.demo;public abstract class Animal {public abstract void eat();
}
//------------------------------------------------------------------------
public class Cat extends Animal{@Overridepublic void eat() {System.out.println("猫吃鱼");}
}
//------------------------------------------------------------------------
public class Dog extends Animal implements FireInterface{ //“implements FireInterface” 实现钻火圈这个功能 把里面的方法重写进这个类里@Overridepublic void eat() {System.out.println("狗吃骨头");}@Overridepublic void fire() {
//这样定义 new的所有狗都会钻火圈 而且钻火圈这个功能和狗没什么关系
//所以这类功能应定义到一个接口里去 接口里定义一些额外扩展的功能 而不是与类相关的功能 与类相关的功能肯定是定义在类里的System.out.println("狗经过后天的学习,学会了钻火圈");}
}
//------------------------------------------------------------------------
public interface FireInterface { //定义一个接口//接口中定义的是抽象方法public abstract void fire();
}
package org.westos.demo;public class MyTest {public static void main(String[] args) {//接口:与类同级别,接口主要用来定义一些扩展额外的功能,那哪些事物,想要具备这些功能,可以去实现这个接口//如何定义一个接口,使用关键字 interfaceAnimal an = new Cat();an.eat();Dog dog = new Dog();an = dog;an.eat();FireInterface fireInterface = dog;fireInterface.fire();//接口不能实例化 按照多态方式实例化(不能去new接口的对象)}
}
package org.westos.demo;public class MyTest {public static void main(String[] args) {}
}
//------------------------------------------------------------------------
interface AA{public abstract void aa();public abstract void show();}
//------------------------------------------------------------------------
class BB implements AA{ // implements 实现关系 :子类实现接口
//你一个普通的类,要实现一个接口,那么得全部重写接口中所有的抽象方法@Overridepublic void aa() {}@Overridepublic void show() {}
}
接口的成员特点
- 接口成员特点
- 成员变量;只能是常量,并且是静态的。
默认修饰符:public static final
建议:自己手动给出。 - 构造方法:接口没有构造方法。
- 成员方法:只能是抽象方法。
默认修饰符:public abstract
建议:自己手动给出。
- 成员变量;只能是常量,并且是静态的。
package org.westos.demo;public interface MyInterface { //接口中语法特点:public static final int NUM = 100; //接口中没有变量 全是 公共的静态常量 //int NUM = 100 前面有默认的缺省的修饰符 public static final 不写也有int B=10;//公共的静态常量 //前面有默认的修饰符 public static final//接口中没有非抽象方法,全是抽象方法public abstract void aa();void bb(); //前面有默认的修饰符 public abstract //没写 默认肯定是抽象方法//public void hehe(){}; 报错,接口不能有非抽象方法//接口中没有构造方法
}
package org.westos.demo;public class MyTest {public static void main(String[] args) {int num = MyInterface.NUM;//接口名可以直接调用 公共静态常量用接口名直接调用就行 不要new也不允许newSystem.out.println(num);}
}
类与类,类与接口,接口与接口的关系
- 类与类,类与接口,接口与接口的关系
a:类与类:
继承关系,只能单继承,可以多层继承。
b:类与接口:
实现关系,可以单实现,也可以多实现。
并且还可以在继承一个类的同时实现多个接口。
c:接口与接口:
继承关系,可以单继承,也可以多继承。
package org.westos.demo;public class MyTest {public static void main(String[] args) {//类跟类的关系//类跟类的关系,是继承关系 extends,但只能是单继承//类跟接口的关系//类跟接口的关系,是实现关系,implments 实现可以多实现,一个类可以实现多个接口//我们一个类可以在继承一个类的同时,并且也可以去实现一个或多个接口//接口跟接口的关系//接口跟接口有继承关系,而且支持多继承}
}
abstract class Fu{public abstract void fu();
}
//------------------------------------------------------------------------
interface A{void a();void aa();
}
//------------------------------------------------------------------------
interface B{void b();void bb();
}
//------------------------------------------------------------------------
interface C{void c();
}
//------------------------------------------------------------------------
class MyClass extends Fu implements A,B,C{ //一个类可以实现多个接口 每个接口的抽象方法必须全部实现//一个类可以在继承一个类的同时,并且也可以去实现一个或多个接口 //也必须实现父类里的抽象方法@Overridepublic void a() {}@Overridepublic void aa() {//空实现 //里面没写具体逻辑}@Overridepublic void b() {}@Overridepublic void bb() {}@Overridepublic void c() {}@Overridepublic void fu() {}
}
//------------------------------------------------------------------------
interface AA{void a();void aa();
}
//------------------------------------------------------------------------
interface BB{void b();void bb();
}
//------------------------------------------------------------------------
interface CC extends AA,BB{ //接口跟接口有继承关系,而且支持多继承void cc();
}
//------------------------------------------------------------------------
class DD implements CC{@Overridepublic void a() {}@Overridepublic void aa() {}@Overridepublic void b() {}@Overridepublic void bb() {}@Overridepublic void cc() {}
}
抽象类与接口的区别
- 成员区别
抽象类:
成员变量:可以变量,也可以常量
构造方法:有
成员方法:可以抽象,也可以非抽象
接口:
成员变量:只可以常量
成员方法:只可以抽象 - 关系区别
类与类
继承,单继承
类与接口
实现,单实现,多实现
接口与接口
继承,单继承,多继承 - 设计理念区别
抽象类 被继承体现的是:”is a”的关系。 抽象类中定义的是该继承体系的共性功能。
接口 被实现体现的是:”like a”的关系。 接口中定义的是该继承体系的扩展功能。
package org.westos.demo;public interface AA{void test();public default void aa(){System.out.println("aa方法的具体功能实现");}
}
//------------------------------------------------------------------------
interface BB{//JDK1.8之后,可以有用 default修饰的方法 //default:接口默认方法实现default void bb() {System.out.println("bb方法的具体功能实现");}
}
//------------------------------------------------------------------------
class EE implements AA,BB{@Overridepublic void test() {System.out.println("test");}
}
package org.westos.demo;public class MyTest {public static void main(String[] args) {//抽象类跟接口的区别—————
//成员变量的区别:抽象类中可以定义成员变量,也可以定义常量 接口中只能是公共的静态常量,使用接口名可以直接调用
//构造方法的区别:抽象类中有构造方法,接口中没有构造方法
//成员方法的区别:抽象类中可以有抽象方法,也可以有非抽象方法,接口中只能是抽象方法(JDK1.7之前)
//设计理念的区别,抽象类体现是一种is a的关系(继承共性 什么是什么),接口 like a 的关系(继承扩展什么像什么)//抽象类跟接口的共同点,抽象类和接口,不能直接实例化
//JDK1.8之后,接口中可以定义默认方法,默认方法可以有方法体//C类 A类 B类:C类想继承A类和B类中的方法 但是由于单继承 类每次只能继承一个类 不能多继承几个类
//C类 A接口 B接口:C类可以同时实现A接口和B接口中的所有方法 弥补了单继承的不足
//类每次只能单继承一个类 不能多继承几个类 为了解决这个问题 出现了接口中写具体实现方法以及可以同时实现多个接口
/* JDK1.7之前A接口和B接口里面定义的是抽象方法 方法在接口中没有做实现 实现的东西是自己写的 自己把它实现了
但是现在我们不想自己去实现 就想拿来现成的就直接用
所以JDK1.8之后让接口中出现一种方法 这种方法有它具体的功能实现
即在接口中把方法实现写好之后 类可以随意继承多个接口里面的方法 可以弥补单继承的不足 */EE ee = new EE(); //接口中只能是公共的静态常量,使用接口名可以直接调用ee.aa(); //ee可以用第一个接口中的 aa方法ee.bb(); //ee可以用第二个接口中的 bb方法//弥补了类的单继承的不足}
}
//abstract class A{ //抽象类中可以定义成员变量,也可以定义常量
// int num=100;
// public static final int A=10;
//}
接口的案例
猫狗案例加入跳高功能分析及其代码实现
A:案例演示
动物类:姓名,年龄,吃饭,睡觉。
动物培训接口:跳高
猫继承动物类
狗继承动物类
部分猫继承猫类并实现跳高接口
部分狗继承狗类并实现跳高接口
通过抽象类测试基本功能。
通过接口测试扩展功能。
package org.westos.demo;
public abstract class Animal {public String name;public int age;public abstract void eat();//定义成抽象的 强制子类去重写public abstract void sleep();
}
//------------------------------------------------------------------------
package org.westos.demo;
public interface JumpInterface {void jump();
}
//------------------------------------------------------------------------
package org.westos.demo;
public class Cat extends Animal{@Overridepublic void eat() {System.out.println("吃饭");}@Overridepublic void sleep() {System.out.println("睡觉");}
}
//------------------------------------------------------------------------
package org.westos.demo;
public class Dog extends Animal{@Overridepublic void eat() {System.out.println("吃饭");}@Overridepublic void sleep() {System.out.println("睡觉");}
}
//------------------------------------------------------------------------
package org.westos.demo;
public class Tom extends Cat implements JumpInterface{@Overridepublic void eat() {System.out.println("汤姆爱吃杰瑞");}@Overridepublic void sleep() {System.out.println("汤姆不睡觉");}@Overridepublic void jump() {System.out.println("tom经过不断的学习,学会了跳高");}public void tom() {System.out.println("tom特有的功能");}
}
//------------------------------------------------------------------------
package org.westos.demo;
public class BigFaceCat extends Cat{@Overridepublic void eat() {System.out.println("大脸猫爱吃蓝皮鼠");}@Overridepublic void sleep() {System.out.println("大脸猫天天睡觉");}
}
//------------------------------------------------------------------------
package org.westos.demo;
public class WaiCaiDog extends Dog{@Overridepublic void eat() {System.out.println("旺财爱吃骨头");}@Overridepublic void sleep() {System.out.println("旺财睡觉打呼噜");}public void lookDoor(){System.out.println("看门");}
}
//------------------------------------------------------------------------
package org.westos.demo;
public class GaoFeiDog extends Dog implements JumpInterface{@Overridepublic void eat() {System.out.println("高飞狗吃饼干");}@Overridepublic void sleep() {System.out.println("高飞狗睡觉睡不醒");}@Overridepublic void jump() {System.out.println("高菲学会了跳高");}
}
//------------------------------------------------------------------------
package org.westos.demo;public class MyTest {public static void main(String[] args) {//A://案例演示//动物类: 姓名,年龄,吃饭,睡觉。//动物培训接口:跳高//猫继承动物类//狗继承动物类//部分猫继承猫类 并实现跳高接口//部分狗继承狗类 并实现跳高接口////通过抽象类 测试 基本功能。//通过接口 测试 扩展功能。//只测试猫,狗的测试留给学生自己练习Tom tom = new Tom();Cat cat=tom;cat.name="Tom";cat.age=2;System.out.println(cat.name+"==="+cat.age);cat.eat();cat.sleep();((Tom) cat).tom(); //向下转型 //可以调tom特有功能//多态//父接口引用,执行子类对象JumpInterface jumpInterface=tom;jumpInterface.jump();}
}
14 面对对象(多态;抽象类;接口)相关推荐
- day09 多态抽象类接口
多态抽象类接口 1:final关键字可以干什么?有什么特点? 2:final关键字的面试题? 3:多态是什么,前提是什么? 4:多态中成员访问的特点? 5:多态的好处及弊端?如何解决多态的弊端? 6: ...
- Java面对对象(多态)
Java面对对象(多态) 一,object类和toString Object 类|老祖宗类 是java 中所有类的父类 在java中的所有类都会直接或者间接的继承自Object类 to ...
- 继承 多态 抽象类 接口
面向对象编程 包 继承 组合 多态 抽象类 接口 包 包(package)是组织类的一种方式. 使用包的主要目的是保证类的唯一性. java中已经提供给我们很多现成的类供我们选择,例如可以使用 imp ...
- java面对对象-多态
什么是多态1.面向对象的三大特性:封装.继承.多态.从一定角度来看,封装和继承几乎都是为多态而准备的.这是我们最后一个概念,也是最重要的知识点. 2.多态的定义:指允许不同类的对象对同一消息做出响应. ...
- 初始Java Java SE 包,继承,组合,多态,抽象类,接口
目录 包 1.静态导入 2.将类放到包中 3.包的访问权限控制 继承 基本语法: 注意事项: protected 关键字 final 关键字 组合 多态 向上转型: 动态绑定 方法重写 重写的规则 : ...
- java ee2019 11 5关于多态 抽象类 接口
1 猫狗案例 多态版(继承版) class Animal{//成员方法private String name ; private int age ;//无参构造public Animal(){}//有 ...
- JavaSE 多态 抽象类 接口
day09目录: 多态(动态绑定机制)多态的概述多态的成员访问特点多态的好处和弊端向上转型和向下转型多态内存图 抽象类抽象类的概述抽象类的成员特点抽象类的案例 接口接口的概述接口的成员特点类与类,类与 ...
- object+多态+抽象类+接口
一.object 定义:object是java所有类的父类,Java中所有类都直接或间接的继承object,Java是单继承机制·,·一个类如果没有显示继承其他类时,就默认他继承object类 常用方 ...
- java自学 part2 数组 类和对象 包 继承 多态 抽象类 接口
数组:arr 获取数组的长度:arr.length 数组转字符串: Arrays.toString(arr) 数组的拷贝: Arrays.copyOf(arr,arr.length) 数组的排序:Ar ...
最新文章
- Python求解线性方程组
- 听说蒂姆·库克来了?这和我们有什么关系!
- firefox扩展开发(四) : 更多的窗口控件
- android服务器 性能,Android性能优化(中)
- JS-内置对象内置构造函数事件-拖拽轮播图无缝滚动
- 基于JAVA+SpringBoot+Mybatis+MYSQL的体育馆开放管理系统
- 前端笔记 | CSS定位
- 深度学习5-模型的保存与加载
- 从Slice_Header学习H.264(三.1)--相关细节之 POC的计算
- 产品开发的生命周期管理
- 【梳理】离散数学 第15章 欧拉图与哈密顿图 15.3 最短路问题、中国邮递员问题与货郎担问题
- Educoder CC++数组实训
- 2022双十一最亮投影仪推荐,当贝X3激光投影3200ANSI流明超高亮度
- Please, configure Web Facet first!的解决办法
- cuda9.0+cudnn7.0 +tensorflow1.5(1.6) 报错:ImportError: libcublas.so.9.0: cannot op
- 单核CPU能够实现并行么?
- Spring 的控制反转/依赖注入
- 为什么delphi编译生成的exe文件这么大?
- 学习了编程之后,是不是就可以进行APP开发了?
- 浅谈猪场的信息化管理
热门文章
- 龙芯3a5000下编译redis 7.0源码
- 统一调度平台V2.0
- 视频号的播放量和互动率、完播率密不可分
- 问题 C: 考试排名(一)(结构体专题)
- 3dsmax Node Event System
- 项目专题 1: 结构化方法学自动取款机系统(ATM)分析
- 安鸾渗透实战平台综合渗透——SQL注入进阶渗透流程
- 如何根据选股条件选择基本面量化股票池?
- class io.netty.util.internal.PlatformDependent0$6 cannot access class jdk.internal.misc.Unsafe
- 怎么阻止流氓软件在电脑里自动安装软件?