继承补充:
动物园里有很多种动物:
比如说,狗,猫等。
狗有姓名和年龄,猫也有姓名和年龄。
狗有跑步的方法,猫也有跑步的方法。而且都仅仅是跑步。
狗有吃饭的方法,猫也有吃饭的方法。只不过,狗吃骨头,猫吃鱼。
请用所学知识,对这个问题进行解决。
父类
成员变量
成员方法
子类
重写方法
特有方法
测试类
普通调用
package com.itheima.demo;
public class animal {
String name;
int age;
public void run(){
System.out.println("仅仅会跑步");
}
public void eat(){
System.out.println("动物都吃饭");
}
}
package com.itheima.demo;
public class cat extends animal{
@Override
public void eat() {
super.eat();
System.out.println("猫吃鱼");
}
}
package com.itheima.demo;
public class dog extends animal {
@Override
public void eat() {
super.eat();
System.out.println("狗吃骨头");
}
}
package com.itheima.demo;
public class antest {
public static void main(String[] args) {
/* cat cat = new cat();
cat.name = "hellokitty";
cat.age = 2;
System.out.println(cat.name);
cat.run();
cat.eat();*/
animal an = new cat();//或者可以先对子类实例化,然后用父类指向子类
an.name = "hellokitty";
an.age=2;
System.out.println(an.name);
System.out.println(an.age + "岁");
an.run();
an.eat();
System.out.println("-----------------------");
an = new dog();
an.name = "泰迪";
an.age = 1;
System.out.println(an.name);
System.out.println(an.age + "岁");
an.run();
an.eat();
}
}
多态
概念
:某一事物在不同时刻表现出来的不同状态
Cat c = new Cat()//猫是猫类型
Animal an = new Cat()//猫是动物类型
产生多态的前提:
1.要有继承关系
2.要有方法重写
3.要有父类引用指向子类对象。
Fu fu = new zi()//输出的是子类的属性方法、
多态中成员方法访问的特点
1.成员变量:编译看左边,运行看右边。
2.构造方法:创建子类对象的时候,会访问父类的构造方法,对父类的数据进行初始化。
3.成员方法:编译看左边,运行看右边。
4.静态方法:编译看左边,运行看左边。
多态的好处
1.提高了代码的维护性
2.提高了代码的扩展性。
多态的弊端:
不能使用子类特有的功能。
解决方法:吧父类的引用强制转换为子类的引用也就是向下转型。
ZI zi = =(Zi) fu /向下转型
Fu fu = new zi//强制类型转换,向上转型
fu = new zi1(也就是同一个里面的另一个类 可以直接用父类指向)
读代码
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 DuoTaiTest4 {
public static void main(String[] args) {
A a = new B();
a.show(); // 爱
B b = new C();
b.show();// 你
}
}
//解读思路:A是爷爷类 B是儿子类 C是孙子类
A a = new B();强制类型转换 不过先要初始化父类 所以是show()方法调用show2();然后强制转换输出子类的show2()结果。
B b = new C();B的show2()强制抓换成C的show()方法 输出结果。
抽象
概念:
一个没有方法体的方法定义为抽象方法。如果类中有抽象方法,该类必定为抽象类
使用思想就是抽取所有子类的共性,但是不给出具体的功能实现,而是交由子类根据自身的特性来实现。
使用关键字 abstract 该关键字可以修饰类也可以修饰方法
抽象类的格式:abstract class 类名{}
抽象方法的格式:public abstract void eat();
抽象类的特点:
-
抽象类不一定有抽象方法,但是抽象方法一定是抽象类。
-
抽象类中可以有构造方法,这个时候这个构造方法的作用就是用于子类访问父类数据时的初始化。
-
但是抽象类不能进行实例化 例如:new a 是不能存在的,但是可以采用多态的形式间接实例化
按照多态的方式,由具体的子类实例化。也就是抽象类多态。
-
抽象类中的所有抽象方法强制子类必须重写。非抽象方法可以让子类直接继承使用,对于抽象方法,子类必须重写。
抽象类的成员特点:
成员变量:即可以是常量,也可以是变量。
成员方法:
抽象方法:强制要求子类做的事情。
非抽象方法:子类继承的事情,提高代码的复用性。
案例:
假如我们在开发一个系统时需要对员工(Employee)类进行设计,员工包含3个属性:姓名、工号以及工资(salary)。
经理(Manager)也是员工,除了含有员工的属性外,另为还有一个奖金(bonus)属性。
然后定义工作的方法.
请使用继承的思想设计出员工类和经理类。
package com.itheima.demo1;
public abstract class staff {
public String name;
public int id;
public double sal;
public abstract void work();
}
package com.itheima.demo1;
public class manager extends staff{
double bonus;
@Override
public void work() {
System.out.println("经理签字工作");
}
}
package com.itheima.demo1;
public class employee extends staff {
@Override
public void work() {
System.out.println("员工在一线工作");
}
}
package com.itheima.demo1;
public class mytest1 {
public static void main(String[] args) {
staff st = new manager();//强制类型转换,向上转换。用父类调用输出
st.id = 46732;
st.name = "cherry";
st.sal = 6372;
System.out.println(st.id);
System.out.println(st.sal);
System.out.println(st.name);
st.work();
manager st1 = (manager) st; //强制类型转换 向下转换,子类的特有功能 强制转换回子类进行调用
st1.bonus = 43256;
System.out.println("经理奖金" + st1.bonus);
System.out.println("-------------");
st = new employee();//直接用父类指向,就可以,因为前面已经定义
st.id = 65;
st.name = "蒲小姐";
st.sal = 2567;
System.out.println(st.name);
System.out.println(st.sal);
System.out.println(st.id);
st.work();
}
}
一个类如果没有抽象方法,可以定义为抽象类,但是不能创建对象
abstract不能共存的关键字:
private: 私有 无法继承
fianl:子类不能重写。
static:不参与重写。不能共存,没意义。
接口
概述:
为了体现事物的扩展性,java中定义提供了接口来定义这些额外的功能。哪些事物想要具备这些功能,可以对该接口实现。
使用关键字interface表示
接口定义的格式
接口用关键字interface表示
interface 接口名{}
类实现接口名
类实现接口用implements 表示
class 类名 implements 接口名{}
将新增的功能写在类中,
在接口中定义新的功能让,只给出方法 不给出具体实现。
接口不能实例化,也就是不能直接new对象。所以用父接口指向子对象,然后接口.方法();
jumpinteface jumpinterface = cat//cat是前面new过的cat
jumpInterface.jump();//实现接口中cat的功能
接口的子类
接口剖的子类可以是抽象类,也可以是具体类。推荐使用具体类。
接口中的成员变量是公共的静态的前面存在默认的修饰符
public static final
接口中没有构造方法。
接口中的成员方法只能是抽象方法。 默认修饰符:public abstract
类与类,类与接口,接口与接口之间的对象
- 类与类是继承关系。只能是单继承,可以多层继承。
- 类与接口是实现关系,可以单实现,也可以多实现。并且可以在实现类的同时实现多个接口。接口与接口之间用逗号隔开就可以(英文逗号)
- 接口与接口:继承关系:可以单继承也可以多继承。
java中的接口更多的是来定义一些规则和规范,以实现扩展性
抽象类和接口的区别:
1.成员区别
成员变量 | 成员方法 | 构造方法 | |
---|---|---|---|
抽象类 | 变量,常量 | 可以抽象,可以非抽象 | 有构造方法,进行实例化的 |
接口类 | 只可以是常量 | 只可以抽象 | 无 |
2.关系区别
类与类 | 继承。单继承 |
---|---|
类与接口 | 实现,单实现,多实现 |
接口与接口 | 继承,单继承,多继承 |
3.设计理念的区别
抽象类 被继承体现的是”is a“ 的关系,抽象类中定义的是该继承体系的共性功能
接口:被实现体现的是“like a" 的关系。接口中定义的是该继承体系的扩展功能。
jdk1.8对接口做了一些新的定义,允许给出方法的具体实现。但是这个方法要用fefault来修饰。
代码:
某学校的老师有基础班的,也有就业班的。
共性:
属性:姓名,年龄
功能:讲课。
现在又要针对日语这种小语种单独开班,
需要部分基础班老师和部分就业班老师会说日语。
请用所学知识把上面的内容用代码体现。
package com.itheima.demo3;
public abstract class teacher {
String name;
int age;
public abstract void teach();//要继承使用 用抽象 子类具有该方法,但是每个功能不一样。
}
package com.itheima.demo3;
public class baseteacher extends teacher {
@Override//方法重写
public void teach() {
System.out.println("基础班老师讲基础");//写出自己的方法所要实现的功能
}
}
package com.itheima.demo3;
public class workteacher extends teacher {
@Override
public void teach() {
System.out.println("就业班老师讲就业指导");
}
}
package com.itheima.demo3;
public class somebaseteacher extends baseteacher implements sayjapanessinterface{
@Override
public void sayjapaness() {
System.out.println("部分基础班老师会讲日语");
}
}
package com.itheima.demo3;
public class someworkteacher extends workteacher implements sayjapanessinterface {
@Override
public void sayjapaness() {
System.out.println("部分就业班老师会讲日语");
}
}
package com.itheima.demo3;
public interface sayjapanessinterface {
void sayjapaness();
}
package com.itheima.demo3;
public class thtest {
public static void main(String[] args) {
somebaseteacher sbt = new somebaseteacher();//实例化子类
baseteacher bt = sbt;//父类指向子类,因为接口中只能这样输出,
bt.name = "shenmoumou";
bt.age = 37;
System.out.println(bt.name);
System.out.println(bt.age);
bt.teach();
((somebaseteacher) bt).sayjapaness();//父类输出子类里面的内容
System.out.println("--------------");
someworkteacher swt = new someworkteacher();
workteacher wt = swt;
wt.name = "nana";
wt.age = 30;
System.out.println(wt.name);
System.out.println(wt.age);
wt.teach();
((someworkteacher) wt).sayjapaness();
}
}