文章目录
- 回顾
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{
@Override
public void eat() {
System.out.println("猫爱吃鱼");
}
public void catchMouse(){
System.out.println("抓老鼠");
}
}
//------------------------------------------------------------------------
public class Dog extends Animal{
@Override
public 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接受Cat
an.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{
@Override
public void eat() {
System.out.println("老虎吃鸡");
}
}
//------------------------------------------------------------------------
public class Fox extends Animal{
@Override
public 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("子类构造执行了");
}
@Override
public 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{
@Override
public void eat() {
System.out.println("猫吃鱼");
}
public void catcheMouse(){
System.out.println("猫抓老鼠");
}
}
//------------------------------------------------------------------------
public class Dog extends Animal{
@Override
public 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转型为Cat
cat.catcheMouse();
}
}
package org.westos.demo;
public class MyTest {
public static void main(String[] args) {
/*
* 听说孔子爹JavaSE讲的很好,张三慕名前来,把孔子爹请到家里去给他讲课去了
* 那么这个时候,李四也来到孔子家里,请孔子爹讲JavaSE 孔子一看学员来了,孔子爹又不在家,
* 孔子又不想失去这个学员,孔子经过乔装打扮,装成他爹的样子,给李四讲课,他只会讲论语,
* 讲完之后,把李四打发走了,孔子想玩游戏了,卸下这套装扮,去开心的玩游戏去了
* */
孔子爹 k爹 = new 孔子(); //多态:向上转型 //孔子要装成孔子爹的模样 即向上转型
System.out.println(k爹.age); //外在表现 age 60
k爹.teache();
孔子 k = (孔子) k爹; //向下转型 //孔子想玩游戏了,卸下这套装扮 即向下转型
System.out.println(k.age); //外在表现 age 30
k.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);//100
fu.show();//zi Show //当子类中重写了父类方法后 用多态的形式去调 还是以子类重写过后的为准
Son son = (Son) fu;
System.out.println(son.num);//19
son.method();//子类特有的方法
}
}
//------------------------------------------------------------------------
class Father {
int num = 100;
public void show() {
System.out.println("fu show");
}
}
//------------------------------------------------------------------------
class Son extends Father {
int num = 19;
@Override
public 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{
@Override
public void eat() {
System.out.println("猫吃鱼");
}
public void catchMouse(){
System.out.println("抓老鼠");
}
}
//------------------------------------------------------------------------
public class Dog extends Animal{
@Override
public 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 的构造方法");
}
//当一个类,继承了一个抽象类,那么这个抽象类中的所有抽象方法,子类必须重写
@Override
public void eat() {
System.out.println("狗吃骨头");
}
@Override
public void sleep() {
System.out.println("狗趴着睡觉");
}
}
//------------------------------------------------------------------------
public class Cat extends Animal{
@Override
public void eat() {
System.out.println("猫吃鱼");
}
@Override
public 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里面的抽象方法都要继承
@Override
public void test() {
}
@Override
public 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 {
@Override
public void eat() {
System.out.println("猫吃鱼");
}
public void catchMouse(){
System.out.println("猫抓老鼠");
}
}
//------------------------------------------------------------------------
public class Dog extends Aniaml{
@Override
public 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 {
@Override
public void work() {
System.out.println("做一些一线的工作");
}
}
//------------------------------------------------------------------------
class Manager extends Person {
double bonus;
@Override
public 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{
@Override
public void eat() {
System.out.println("猫吃鱼");
}
}
//------------------------------------------------------------------------
public class Dog extends Animal implements FireInterface{
//“implements FireInterface” 实现钻火圈这个功能 把里面的方法重写进这个类里
@Override
public void eat() {
System.out.println("狗吃骨头");
}
@Override
public 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) {
//接口:与类同级别,接口主要用来定义一些扩展额外的功能,那哪些事物,想要具备这些功能,可以去实现这个接口
//如何定义一个接口,使用关键字 interface
Animal 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 实现关系 :子类实现接口
//你一个普通的类,要实现一个接口,那么得全部重写接口中所有的抽象方法
@Override
public void aa() {
}
@Override
public 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也不允许new
System.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{ //一个类可以实现多个接口 每个接口的抽象方法必须全部实现
//一个类可以在继承一个类的同时,并且也可以去实现一个或多个接口 //也必须实现父类里的抽象方法
@Override
public void a() {
}
@Override
public void aa() {
//空实现 //里面没写具体逻辑
}
@Override
public void b() {
}
@Override
public void bb() {
}
@Override
public void c() {
}
@Override
public 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{
@Override
public void a() {
}
@Override
public void aa() {
}
@Override
public void b() {
}
@Override
public void bb() {
}
@Override
public 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{
@Override
public 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{
@Override
public void eat() {
System.out.println("吃饭");
}
@Override
public void sleep() {
System.out.println("睡觉");
}
}
//------------------------------------------------------------------------
package org.westos.demo;
public class Dog extends Animal{
@Override
public void eat() {
System.out.println("吃饭");
}
@Override
public void sleep() {
System.out.println("睡觉");
}
}
//------------------------------------------------------------------------
package org.westos.demo;
public class Tom extends Cat implements JumpInterface{
@Override
public void eat() {
System.out.println("汤姆爱吃杰瑞");
}
@Override
public void sleep() {
System.out.println("汤姆不睡觉");
}
@Override
public void jump() {
System.out.println("tom经过不断的学习,学会了跳高");
}
public void tom() {
System.out.println("tom特有的功能");
}
}
//------------------------------------------------------------------------
package org.westos.demo;
public class BigFaceCat extends Cat{
@Override
public void eat() {
System.out.println("大脸猫爱吃蓝皮鼠");
}
@Override
public void sleep() {
System.out.println("大脸猫天天睡觉");
}
}
//------------------------------------------------------------------------
package org.westos.demo;
public class WaiCaiDog extends Dog{
@Override
public void eat() {
System.out.println("旺财爱吃骨头");
}
@Override
public void sleep() {
System.out.println("旺财睡觉打呼噜");
}
public void lookDoor(){
System.out.println("看门");
}
}
//------------------------------------------------------------------------
package org.westos.demo;
public class GaoFeiDog extends Dog implements JumpInterface{
@Override
public void eat() {
System.out.println("高飞狗吃饼干");
}
@Override
public void sleep() {
System.out.println("高飞狗睡觉睡不醒");
}
@Override
public 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();
}
}