继承extends (特点、重写、覆盖、应用)抽象abstract(定义、特点、细节)
一 继承:
在java中,在现有的类中新建一个类叫子类,现有的类叫父类,子类自动拥有父类所有可继承的属性和方法。关键字 extends Java 只支持单继承
格式:
class 子类 extends 父类 { }
package com.oracle.Demo01; //这是一个父类 public class Developer { String name; public void speak(){ System.out.println(name+"父类正在工作"); } } ------------------------------------------------------- package com.oracle.Demo01; //子类 public class JavaEE extends Developer{ public void print(){ System.out.println(name+"子类在写JavaEE代码"); } } --------------------------------------------------------- package com.oracle.Demo01; //新建Android类 public class Andriod extends Developer{ public Andriod() { System.out.println("这是安卓里面添加的内容 "); } } --------------------------------------------------------- package com.oracle.Demo01; //测试类 public class Demo01 { public static void main(String[] args) { JavaEE java=new JavaEE(); java.name="钢铁侠"; java.speak(); java.print(); Andriod an=new Andriod(); an.name="小辣椒"; an.speak(); } }
继承的好处和注意事项
好处:1.提高代码复用性 2.产生关系
1.java里,类只支持单继承
class A{}
class B{}
class C extends A,B{} // C类不可以同时继承A类和B类
2.多个类可继承一个父类 一个父亲多个儿子
class A{}
class B extends A{}
class C extends A{} // 类B和类C都可以继承类A
3.多层继承:爷孙关系
class A{}
class B extends A{} // 类B继承类A,类B是类A的子类
class C extends B{} // 类C继承类B,类C是类B的子类,同时也是类A的子类
package com.oracle.Demo02; //父类 public class Fu { int a=1; public void show(){ System.out.println("这是父类的方法"); } } ---------------------------------------------------------------- package com.oracle.Demo02; //子类 public class Zi extends Fu{ int a=2; public void get(){ int a=3; System.out.println(a);//3 就近原则 System.out.println(this.a);//2 用this就等于本类了 //super:父类对象 //注意:this 和super 只能在子类里面使用 System.out.println(super.a); } public void show2(){ System.out.println("这是子类的方法"); } } -------------------------------------------------------------------- package com.oracle.Demo02; //测试类 public class Demo01 { public static void main(String[] args) { //继承中子父类有同名变量时,如果子类自己有,用自己的,如果子类没有,用父类的 Zi zi=new Zi(); System.out.println(zi.a); zi.show();//调用子类的show方法 ,子类里面没有show,子继承了父的show,测试打印子里的show就等于是调用了父类的show zi.show2();//调用子类的show2方法 } }
方法重写:有继承关系前提下,子类中有跟父类,返回值,方法,个数一模一样
package com.oracle.Demo03; //这是父类 public class Phone { public void show(){ System.out.println("显示电话号码"); } public void sendMssage(){ System.out.println("发短信"); } public void call(){ System.out.println("打电话"); } } ------------------------------------------------------- package com.oracle.Demo03; //子类 public class Iphone extends Phone{
//用super调用父类 public void show(){ super.show(); System.out.println("显示来电姓名"); System.out.println("显示头像"); } } -------------------------------------------------------- package com.oracle.Demo03; //测试 用继承和方法重写的 public class Demo01 { public static void main(String[] args) { Iphone iphone =new Iphone(); iphone.show(); iphone.call(); iphone.sendMssage(); } }
l 成员方法特殊情况——覆盖
子类中出现与父类一模一样的方法时,会出现覆盖操作,也称为override重写、复写或者覆盖。
①子类覆盖方法:必须要保证权限大于等于父类权限
4个修饰符的大小关系 :public protected default private
PM
二、抽象类:
1、含义:方法功能声明相同,方法功能主体不同。这时抽取方法声明,不抽取方法主体。此方法就是一个抽象方法。此方法的类就是抽象类。
2、抽象类及抽象方法的定义:
abstract class 类名 {} public abstract 返回值类型 方法名(参数);
package com.oracle.Demo04; //图形类 //抽象类里不一定包含抽象方法,但有抽象方法的类一定是抽象类 public abstract class Huge { //声明一个抽象方法体 public abstract double getArea();
//抽象类里可以写普通方法 public void show(){ System.out.println("这是一个图形"); } } ---------------------------------------------------------- package com.oracle.Demo04; //子体 圆形 //继承一个抽象类,必须要重写 ,如果不想重写就在class前面加abstract,否则报错 public class Circle extends Huge{ //圆形半径 double r; //不加abstract就要重写huge里的方法 如下 @Override //override 重写标记(可删可不删) public double getArea() { double area=2*r*Math.PI; return 0; } } ------------------------------------------------------- package com.oracle.Demo04; //测试 public class Demo01 { public static void main(String[] args) { //声明一个Circle对象 Circle c=new Circle(); c.r=2; double area=c.getArea(); System.out.println("面积为:"+area); } }
3、特点:
①、抽象类、方法都要abstract 修饰
②、有抽象方法的类一定是抽象类
③、抽象类不一定包含抽象方法,也可有普通方法
public abstract class Huge {
public abstract double getArea();//抽象方法
public void show(){ //普通方法
System.out.println("这是一个图形");
}
}
④、抽象类不能new,重写所有方法,成为普通方法,才可以new
⑤、抽象类一定是父类;
⑥、抽象类是子类的父类,把共有的属性抽取出来。子类覆盖了父类所有的抽象方法,子类才能创建对象。否则子类还是个抽象类。
⑦、abstract 和 private 不能共存:private:私有的方法无法继承,也不存在覆盖
练习:
package com.oracle.Demo05; //建一个公共的抽象类 员工 public abstract class Emp { //封装 属性 private int eid; private String ename; public int getEid() { return eid; } public void setEid(int eid) { this.eid = eid; } public String getEname() { return ename; } public void setEname(String ename) { this.ename = ename; } //声明一个抽象的方法 public abstract void work(); } ------------------------------------------------------- package com.oracle.Demo05; //研发 继承抽象员工类 public abstract class Yanfa extends Emp{ } ------------------------------------------------------ package com.oracle.Demo05; //抽象类继承Emp public abstract class Weihu extends Emp{ } ------------------------------------------------------ package com.oracle.Demo05; //继承Yanfa类 public class JavaEE extends Yanfa{ //重写里面方法 @Override public void work() { System.out.println("姓名为"+getEname()+"工号为"+getEid()+"的员工正在写javaEE代码"); } } -------------------------------------------------- package com.oracle.Demo05; //安卓类继承研发类 public class Andriod extends Yanfa{ public void work() { System.out.println("姓名为"+getEname()+"工号为"+getEid()+"的员工正在写Andriod代码"); } } ----------------------------------------------------- package com.oracle.Demo05; //网络工程师继承维护类 public class Network extends Weihu{ //重写weihu类的方法 public void work() { System.out.println("姓名为"+getEname()+"工号为"+getEid()+"的员工正在维护网络"); } } ---------------------------------------------------- package com.oracle.Demo05; //硬件继承维护类 public class HardWare extends Weihu{ //重写weihu的方法 public void work() { System.out.println("姓名为"+getEname()+"工号为"+getEid()+"的员工正在维护硬件"); } } --------------------------------------------------- package com.oracle.Demo05; //测试 public class Demo01 { public static void main(String[] args) { //创建JavaEE员工 JavaEE j=new JavaEE(); j.setEid(1); j.setEname("张三"); //j调用work方法 j.work(); //创建安卓员工 Andriod a=new Andriod(); a.setEid(2); a.setEname("李四"); a.work(); //创建网络员工 Network n=new Network(); n.setEid(3); n.setEname("小红帽"); n.work(); } }
打印的结果
作业:
根据需求,完成如下代码(使用抽象类、按照标准格式写),并在测试类中进行测试。
需求一:
具体事物:基础班老师,就业班老师
共性:姓名,年龄,讲课。
特性:
基础班老师讲JavaSE
就业班老师讲Android
需求二:
具体事物:基础班学生,就业班学生
共性:姓名,年龄,学习
特性:
基础班学生学JavaSE
就业班学生学Android
需求三:
已知猫类和狗类:
属性:毛的颜色,腿的个数
行为:吃饭
猫特有行为:抓老鼠catchMouse
狗特有行为:看家lookHome
写代码
package zuoye; //定义一个公共的抽象的老师类 public abstract class teacher { //封装 private String name; private int age; private String jiangke; public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getJiangke() { return jiangke; } public void setJiangke(String jiangke) { this.jiangke = jiangke; } //创建一个抽象的方法 public abstract void work(); } ----------------------------------------------------------- package zuoye; //让基础老师继承teacher类 public class jc extends teacher{ public void work(){ System.out.println("姓名为:"+getName()+"年龄为:"+getAge()+"岁"+getJiangke()); } } ------------------------------------------------------------- package zuoye; //就业老师继承teacher public class jy extends teacher{ public void work(){ System.out.println("姓名为:"+getName()+"年龄为:"+getAge()+"岁"+getJiangke()); } } ------------------------------------------------------------- package zuoye; //定义学生父类 public abstract class student { //封装属性 private String sname; private int sage; private String study; public String getSname() { return sname; } public void setSname(String sname) { this.sname = sname; } public int getSage() { return sage; } public void setSage(int sage) { this.sage = sage; } public String getStudy() { return study; } public void setStudy(String study) { this.study = study; } //建一个抽象的方法 public abstract void xuexi(); } ------------------------------------------------------ package zuoye; //让基础班继承student类 public class jcstu extends student{ public void xuexi() { System.out.println("姓名为:"+getSname()+"年龄为:"+getSage()+"岁"+getStudy()); } } --------------------------------------------------- package zuoye; //让就业班继承student public class jystu extends student{ public void xuexi() { System.out.println("姓名为:"+getSname()+"年龄为:"+getSage()+"岁"+getStudy()); } } ------------------------------------------------------ package zuoye; //定义一个动物 父类 public abstract class animal { //封装属性 private String color; private int tui; //private String eat; public String getColor() { return color; } public void setColor(String color) { this.color = color; } public int getTui() { return tui; } public void setTui(int tui) { this.tui = tui; } //新建个抽象的方法 public abstract void eat(); } -------------------------------------------------------- package zuoye; //让狗继承animal类 public class dog extends animal{ public void eat(){ System.out.println("一只颜色为:"+getColor()+","+"拥有"+getTui()+"条腿的狗狗,在进食"); } //新建个特有的方法 public void lookhome(){ System.out.println("狗狗特有的行为就是看家"); } } -------------------------------------------------------- package zuoye; //让猫类继承animal类 public class mao extends animal{ public void eat(){ System.out.println("一只颜色为:"+getColor()+","+"拥有"+getTui()+"条腿的猫咪,在进食"); } //新建个特有的方法 public void catchMouse(){ System.out.println("猫特有的行为就是捉老鼠"); } } ----------------------------------------------------------- 最后 测试一下 package zuoye; //测试 public class Demo01 { public static void main(String[] args) { //创建基础班 jc j=new jc(); j.setAge(30); j.setName("基础老师,"); j.setJiangke("在讲JavaSe"); j.work(); //创建就业班 jy a=new jy(); a.setAge(18); a.setName("就业老师,"); a.setJiangke("在讲Andriod"); a.work(); //创建基础班的学生 jcstu jcs=new jcstu(); jcs.setSname("基础学生,"); jcs.setSage(10); jcs.setStudy("在学JavaSE"); jcs.xuexi(); //创建就业班的学生 jystu jys=new jystu(); jys.setSname("就业学生,"); jys.setSage(18); jys.setStudy("在学Andriod"); jys.xuexi(); //创建狗 dog d =new dog(); d.setColor("骚黑色"); d.setTui(4); d.eat(); d.lookhome(); //创建猫 mao m=new mao(); m.setColor("骚白色"); m.setTui(4); m.eat(); m.catchMouse(); } }
打印的结果: