*A:继承的概念 *a:继承描述的是事物之间的所属关系,经过继承可使多种事物之间造成一种关系体系 *b:在Java中,类的继承是指在一个现有类的基础上去构建一个新的类, 构建出来的新类被称做子类,现有类被称做父类 *B:继承关系的子类特色 *a:子类会自动拥有父类全部非private修饰的属性和方法
*A:继承的格式 class 子类 extends 父类 {} *B:雇员(Employee)与研发部员工(Developer)案例: *cn.itcast.demo01包下: *Employee.java: /* * 定义员工类Employee */ class Employee { String name; // 定义name属性 public void work() {// 定义员工的工做方法 System.out.println("全力以赴地工做"); } } *Developer.java: /* * 定义研发部员工类Developer 继承 员工类Employee * 继承了父类中全部非private修饰的成员变量 */ class Developer extends Employee { // 定义一个打印name的方法 public void printName() { System.out.println("name=" + name); } } *测试员工类与研发部员工类: /* * 定义测试类 */ public class Example01 { public static void main(String[] args) { Developer d = new Developer(); // 建立一个研发部员工类对象 d.name = "小明"; // 为该员工类的name属性进行赋值 d.printName(); // 调用该员工的printName()方法 d.work(); // 调用Developer类继承来的work()方法 } } *经过子类对象既能够调用自身的非private修饰的成员,也能够调用父类的非private修饰的成员
*A:继承的好处: *一、继承的出现提升了代码的复用性,提升软件开发效率。 *二、继承的出现让类与类之间产生了关系,提供了多态的前提。
*A:继承的注意事项 *a:在Java中,类只支持单继承,不容许多继承,也就是说一个类只能有一个直接父类,例以下面这种状况是不合法的。 class A{} class B{} class C extends A,B{} // C类不能够同时继承A类和B类 假如支持多继承例如: class A{ int a=3; public void method(){ } } class B{ int a=5; public void method(){ } } class C extends A,B{ } class Demo{ public static void main(String[] args){ C c=new C(); System.out.println(c.a);//究竟是调用A的仍是B的成员变量??没法肯定 c.method();//究竟是调用A的仍是B的成员方法??没法肯定 } } *b:多个类能够继承一个父类,例以下面这种状况是容许的(就像你爹能够多个儿子,可是这些儿子都只有一个爹) class A{} class B extends A{} class C extends A{} // 类B和类C均可以继承类A *c:在Java中,多层继承是能够的, 即一个类的父类能够再去继承另外的父类, 例如C类继承自B类,而B类又能够去继承A类,这时,C类也可称做A类的子类。下面这种状况是容许的。 class A{} class B extends A{} // 类B继承类A,类B是类A的子类 class C extends B{} // 类C继承类B,类C是类B的子类,同时也是类A的子类
java
*d:在Java中,子类和父类是一种相对概念, 也就是说一个类是某个类父类的同时,也能够是另外一个类的子类。 例如上面的这种状况中,B类是A类的子类,同时又是C类的父类。
*A:继承的体系:设计模式
动物(吃) | ------------------------- | | 猫科动物(吃,胎生) 爬行动物(吃,卵生) | | ------------------------------- ----------------- | | | | 猫(吃,抓老鼠,胎生) 虎(吃,领地,胎生) 蛇(吃,冬眠,卵生) 鳄鱼(吃,潜水,卵生) *a:动物体系是对每一个具体事物共性的抽取,子类的共性抽取造成父类 *b:父类:具备全部子类的共性内容 子类:不但有共性还有自身特有的内容 *c:整个继承体系,越向上越抽象,越向下越具体
A:继承后子类父类成员变量的特色 a:子类的对象调用成员变量的时候,子类本身有,使用子类,子类本身没有调用的父类 class Fu{ //Fu中的成员变量。 int num = 5; } class Zi extends Fu{ //Zi中的成员变量 int num2 = 6; //Zi中的成员方法 public void show() { //访问父类中的num System.out.println("Fu num="+num); //访问子类中的num2 System.out.println("Zi num2="+num2); } } class Demo{ public static void main(String[] args) { Zi z = new Zi(); //建立子类对象 z.show(); //调用子类中的show方法 } } b:当子父类中出现了同名成员变量 class Fu{ //Fu中的成员变量。 int num = 5; } class Zi extends Fu{ //Zi中的成员变量 int num = 6; void show(){ //子类的局部变量 int num=7 //直接访问,遵循就近查找原则 System.out.println(num);//7 //子父类中出现了同名的成员变量时 //在子类中须要访问父类中非私有成员变量时,须要使用super关键字 //访问父类中的num System.out.println("Fu num="+super.num);//5 //访问子类中的num2 System.out.println("Zi num2="+this.num);//6 } } class Demo5 { public static void main(String[] args) { Zi z = new Zi(); //建立子类对象 z.show(); //调用子类中的show方法 } }
A:继承后子类父类成员方法的特性 a:子类的对象调用方法的时候,子类本身有,使用子类,子类本身没有调用的父类 class Fu{ public void show(){ System.out.println("Fu类中的show方法执行"); } } class Zi extends Fu{ public void show2(){ System.out.println("Zi类中的show2方法执行"); } } public class Test{ public static void main(String[] args) { Zi z = new Zi(); z.show(); //子类中没有show方法,可是能够找到父类方法去执行 z.show2(); } } b:为何要有重写? class Fu{ public void method(){ //上千行代码 //Fu类中的方法最早存在,那么若是项目需求变了,该方法 //功能不可以知足咱们的需求,此时咱们也不会去改这个方法 //由于项目中可能有大量的功能已经使用到该方法,若是随意修改可能使调用该方法的功能出现问题 //因此使用重写方式基于原有功能提供更强的功能 } } class Zi extends Fu{ } c:子类中出现与父类如出一辙的方法时,会出现覆盖操做,也称为override重写、复写或者覆盖 class Fu{ public void show(){ System.out.println("Fu show"); } } class Zi extends Fu{ //子类复写了父类的show方法 public void show(){ System.out.println("Zi show"); } } public class Test{ public static void main(String[] args) { Zi z = new Zi(); z.show(); //Zi show 子类有直接使用子类 } }
A:方法覆盖的需求 a:案例:好比手机,当描述一个手机时,它具备发短信,打电话,显示来电号码功能, 后期因为手机须要在来电显示功能中增长显示姓名和头像, 这时能够从新定义一个类描述智能手机,并继承原有描述手机的类。 并在新定义的类中覆盖来电显示功能,在其中增长显示姓名和头像功能 b:分析:咱们不改装(破坏)原来的手机,而是再买一个新的智能手机,不但有原有的功能,并且还有特有功能 例:厂商发布新手机都是基于原有手机的升级,不会拿着原有的手机在卖,新产一款 1:分析类的构建: 手机类 属性(成员变量):无 行为(成员方法): 发短信 打电话 来电显示:显示来电号码 智能手机类: 属性(成员变量):无 行为(成员方法): 发短信 打电话 来电显示:显示来电号码,显示姓名和头像 手机类和智能手机类有共性内容: 发短信 打电话 显示来电号码 2:继承关系分析: 对于发短信和打电话功能,让智能手机直接沿用(继承)手机的就能够 可是在智能手机中的来电显示不但实现号码,还显示姓名和头像,一样的都是来电显示功能,智能手机的来电显示比手机的功能更增强大,咱们考虑使用重写
//手机类 class Phone{ public void sendMessage(){ System.out.println("发短信"); } public void call(){ System.out.println("打电话"); } public void showNum(){ System.out.println("来电显示号码"); } } //智能手机类 class NewPhone extends Phone{ //覆盖父类的来电显示号码功能,并增长本身的显示姓名和图片功能 //从现实生活角度考虑沿用原有的showNum方法名便于用户更快熟悉和接受,而不是再起个新的名字 //用户还须要花费大量时间慢慢接受 public void showNum(){ //调用父类已经存在的功能使用super //若是不加super这是调用子类自身的showNum(),本身调用本身,递归 //方法不断入栈致使内存溢出 super.showNum(); //增长本身特有显示姓名和图片功能 System.out.println("显示来电姓名"); System.out.println("显示头像"); } } public class Test { public static void main(String[] args) { new NewPhone().showNum();//来电显示 显示来电姓名 显示头像 } }
A:方法覆盖的注意事项网络
a:权限:子类方法覆盖父类方法,必需要保证权限大于等于父类权限。 四大权限:public>默认=protected>private class Fu{ void show(){ } public void method(){ } } class Zi() extends Fu{ public void show(){//编译运行没问题 } void method(){//编译错误 } } b:方法定义:子类方法和要重写的父类的方法:方法的方法名和参数列表都要同样。 关于方法的返回值: 若是是基本数据类型,子类的方法和重写的父类的方法返回值类型必须相同 若是是引用数据类型,子类的方法和重写的父类的方法返回值类型能够相同或者子类方法的返回值类型是父类方法返回值类型的子类 class Fu{ int show(){ } public Fu method(){ } public Fu method2(){ } } class Zi() extends Fu{ public int show(){//返回值为基本类型的重写 } public Fu method(){//子类的方法和重写的父类的方法返回值类型能够相同 } public Zi method2(){//子类方法的返回值类型是父类方法返回值类型的子类 } } c:重载与重写对比: 重载: 权限修饰符(public private 默认):无关 方法名:重载的两个方法的方法名必须相同 形参列表: 形参类型的顺序不一样 形参的个数不一样 形参的类型不一样 三者至少知足一个 返回值类型: 重载与返回值类型无关 重写: 权限修饰符(public private 默认): 子类方法的权限>=父类的方法的权限 方法名: 子类方法和父类方法必须相同 形参列表: 子类方法和父类方法的形参列表必须相同 返回值类型: 基本类数据类型: 必须相同 引用数据类型: 子类方法的返回值类型和父类方法的返回值类型相同 或者 子类方法的返回值类型是父类方法的返回值类型的 子类
A:抽象类的产生 a:分析事物时,发现了共性内容,就出现向上抽取。会有这样一种特殊状况,就是方法功能声明相同,但方法功能主体不一样。那么这时也能够抽取,但只抽取方法声明,不抽取方法主体。那么此方法就是一个抽象方法。
A:抽象方法定义的格式: a:public abstract 返回值类型 方法名(参数); 抽象类定义的格式: abstract class 类名 { } b:抽象类示例代码: /* * 定义类开发工程师类 * EE开发工程师 : 工做 * Android开发工程师 : 工做 * * 根据共性进行抽取,而后造成一个父类Develop * 定义方法,工做: 怎么工做,具体干什么呀 * * 抽象类,不能实例化对象, 不能new的 * 不能建立对象的缘由: 若是真的让你new了, 对象.调用抽象方法,抽象方法没有主体,根本就不能运行 * 抽象类使用: 定义类继承抽象类,将抽象方法进行重写,建立子类的对象 */ public abstract class Develop { //定义方法工做方法,可是怎么工做,说不清楚了,讲不明白 //就不说, 方法没有主体的方法,必须使用关键字abstract修饰 //抽象的方法,必须存在于抽象的类中,类也必须用abstract修饰 public abstract void work(); }
A:抽象类的使用方式 /* * 定义类,JavaEE的开发人员 * 继承抽象类Develop,重写抽象的方法 */ public class JavaEE extends Develop{ //重写父类的抽象方法 //去掉abstract修饰符,加上方法主体 public void work(){ System.out.println("JavaEE工程师在开发B/S 软件"); } } /* * 定义Android类,继承开发人员类 * 重写抽象方法 */ public class Android extends Develop{ public void work(){ System.out.println("Android工程师开发手机软件"); } } /* * 测试抽象类 * 建立他的子类的对象,使用子类的对象调用方法 */ public class Test { public static void main(String[] args) { JavaEE ee = new JavaEE(); ee.work();//"JavaEE工程师在开发B/S 软件" Android and = new Android(); and.work();//"Android工程师开发手机软件" } }
A:抽象类的特色ide
a:抽象类和抽象方法都须要被abstract修饰。抽象方法必定要定义在抽象类中。 b:抽象类不能够直接建立对象,缘由:调用抽象方法没有意义。 c:只有覆盖了抽象类中全部的抽象方法后,其子类才能够建立对象。不然该子类仍是一个抽象类。 之因此继承抽象类,更多的是在思想,是面对共性类型操做会更简单。 abstract class A{ public abstract void func(); public abstract void func2(); } class A2 extends A{//A2把A中的两个抽象方法都重写掉了 //A2类再也不是抽象类 public void func(){} public void func2(){} } abstract class A3 extends A{//含有抽象方法的类必定是抽象类 public void func(){ } //public abstract void func2();//func2至关于被继承下来 }
A:抽象类的设计思想 a:抽象类的做用:继承的体系抽象类,强制子类重写抽象的方法 抽象员工: 规定一个方法,work工做 EE员工,Android员工 Develop类 抽象类 abstract work(); | ------------- | | EE Android //是我开发的一员必须工做 work(){} work(){}
A:抽象类的细节测试
a:抽象类必定是个父类? 是的,由于不断抽取而来的。 b:抽象类中是否能够不定义抽象方法? 是能够的,那这个抽象类的存在到底有什么意义呢?不让该类建立对象,方法能够直接让子类去使用 (适配器设计模式) /* * 抽象类,能够没有抽象方法,能够定义带有方法体的方法 * 让子类继承后,能够直接使用 */ public abstract class Animal { public void sleep(){ System.out.println("动物睡觉"); } } public class Cat extends Animal{ } public class Test { public static void main(String[] args) { //Cat c = new Cat(); new Cat().sleep();//不让该类建立对象,方法能够直接让子类去使用 } } c:抽象关键字abstract不能够和哪些关键字共存?
1:private:私有的方法子类是没法继承到的,也不存在覆盖,网站
而abstract和private一块儿使用修饰方法,abstract既要子类去实现这个方法, 而private修饰子类根本没法获得父类这个方法。互相矛盾。 /* * 抽象类,能够没有抽象方法,能够定义带有方法体的方法 * 让子类继承后,能够直接使用 */ public abstract class Animal { // private abstract void show(); //抽象方法,须要子类重写, 若是父类方法是私有的,子类继承不了,也就没有了重写 }
this
2:final,暂时不关注,后面学
3:static,暂时不关注,后面学设计
A:员工案例分析:
a:需求描述:code
某IT公司有多名员工,按照员工负责的工做不一样,进行了部门的划分(研发部员工、维护部员工)。 研发部根据所需研发的内容不一样,又分为JavaEE工程师、Android工程师; 维护部根据所需维护的内容不一样,又分为网络维护工程师、硬件维护工程师。 公司的每名员工都有他们本身的员工编号、姓名,并要作它们所负责的工做。 工做内容 JavaEE工程师:员工号为xxx的 xxx员工,正在研发淘宝网站 Android工程师:员工号为xxx的 xxx员工,正在研发淘宝手机客户端软件 网络维护工程师:员工号为xxx的 xxx员工,正在检查网络是否畅通 硬件维护工程师:员工号为xxx的 xxx员工,正在修复打印机
b:继承体系:对象
员工 | -------------------------------------------- | | 研发部员工 维护部员工 | |
------------- -----------
| | | |
JavaEE工程师 Android工程师 网络维护工程师 硬件维护工程师
c:详细描述:
根据员工信息的描述,肯定每一个员工都有员工编号、姓名、要进行工做。
则,把这些共同的属性与功能抽取到父类中(员工类), 关于工做的内容由具体的工程师来进行指定。
工做内容
JavaEE工程师:员工号为xxx的 xxx员工,正在研发淘宝网站 Android工程师:员工号为xxx的 xxx员工,正在研发淘宝手机客户端软件 网络维护工程师:员工号为xxx的 xxx员工,正在检查网络是否畅通 硬件维护工程师:员工号为xxx的 xxx员工,正在修复打印机
建立JavaEE工程师对象,完成工做方法的调用
A:员工案例Employee类的编写:按照分析的继承体系来逐个实现
/* * 定义员工类 * 内容,都是全部子类的共性抽取 * 属性: 姓名,工号 * 方法: 工做 */ public abstract class Employee { private String id;// 员工编号 private String name; // 员工姓名 public String getId() { return id; } public void setId(String id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } //工做方法(抽象方法) public abstract void work(); }
B:员工案例的子类的编写:
/* * 定义研发员工类 * 属于员工中的一种, 继承员工类 * 抽象类Develop 给本身的员工定义本身有的属性 */ public abstract class Develop extends Employee{ } /* * 描述JavaEE开发工程师类 * 工号,姓名 工做方法 * 其余的员工,也具有这些共性,抽取到父类中,本身就不须要定义了 * 是研发部员工的一种,继承研发部类 */ public class JavaEE extends Develop{ //重写他父类的父类的抽象方法 public void work(){ //调用父类的get方法,获取name,id值 System.out.println("JavaEE的工程师开发淘宝"+ super.getName()+".."+super.getId()); } } /* *定义Android工程师 继承 研发部员工类,重写工做方法 */ public class Android extends Developer { @Override public void work() { System.out.println("员工号为 " + getId() + " 的 " + getName() + " 员工,正在研发淘宝手机客户端软件"); } }
/* * 定义维护员工类,属于员工中的一种 * 继承员工类 * 抽象类Maintainer 给本身的员工定义本身有的属性 */ public abstract class Maintainer extends Employee{ } /* * 描述的是网络维护工程师 * 属于维护部的员工,继承维护部类 */ public class Network extends Maintainer{ public void work(){ System.out.println("网络工程师在检查网络是否畅通"+super.getName()+"..."+super.getId()); } }
/* *定义Hardware硬件维护工程师 继承 维护部员工类,重写工做方法 */ public class Hardware extends Maintainer { @Override public void work() { System.out.println("员工号为 " + getId() + " 的 " + getName() + " 员工,正在修复打印机"); } }
把今天的知识点总结一遍。