黑马程序员-面向对象03
2014-02-09 10:11
246 查看
----------------------- android培训、java培训、java学习型技术博客、期待与您交流! ----------------------
1.继承 多个类中存在相同属性和行为时,将这些内容抽取到单独一个类中,那么多个类无需再定义这些属性和行为,只要继承那个类即可。多个类可以称为子类,单独这个类称为父类或者超类。 子类可以直接访问父类中的非私有的属性和行为。 通过 extends 关键字让类与类之间产生继承关系。 1.1继承的优点 1.继承的出现提高了代码的复用性。 2.继承的出现让类与类之间产生了关系,提供了多态的前提。 注意:千万不要为了获取其他类的功能,简化代码而继承。 必须是类与类之间有所属关系才可以继承。所属关系是 is a。 1.2继承的特点 父类:其实是由多个类不断向上抽取共性内容而来的。 java只支持单继承。java虽然不直接支持多继承,但是保留了这种多继承机制,进行改良(多实现)。 为什么不支持多继承呢? 因为当一个类同时继承两个父类时,两个父类中有相同的功能,那么子类对象调用该功能时,运行哪一个呢? 但是java支持多重继承。A继承B B继承C C继承D。 多重继承的出现,就有了继承体系。体系中的顶层父类是通过不断向上抽取而来的。它里面定义的该体系最基本最共性内容的功能。 所以,一个体系要想被使用,直接查阅该系统中的父类的功能即可知道该体系的基本用法。那么想要使用一个体系时,需要建立对象。建议建立最子类对象,因为最子类不仅可以使用父类中的功能。还可以使用子类特有的一些功能。 简单说:对于一个继承体系的使用,查阅顶层父类中的内容,创建最底层子类的对象。 2.继承中子类父类中成员的特点 1:成员变量。 |-- 子类有,就运行子类的变量,子类没有就运行父类的 |-- 方法里有,不去外面找了 ,运行方法中的变量 |-- 子类中,使用父类的成员变量,super.成员变量 2:成员方法。 |-- 子类父类出现了一模一样的方法的时候,子类重写(覆盖)父类的方法override |-- 保证子类方法的权限大于等于父类方法权限 |-- 好处就在与可以提升程序的扩展性 手机案例,重复的直接使用super.方法() 什么时候使用覆盖呢?当一个类的功能内容需要修改时,可以通过覆盖来实现。 3:构造方法。 |-- 子类构造(所有的)方法,必须访问父类的构造方法 |-- 子类的构造方法的第一行隐式代码super(),默认访问父类的空参数的构造方法 |-- 如果父类没有空参数的构造方法,子类的构造方法,没有手动写super 编译失败 |-- 子类之间,可以通过this()语句的形式间接访问父类构造方法 |-- 子类中的方法一定多于父类中的方法吗 发现子类构造函数运行时,先运行了父类的构造函数。为什么呢? 原因:子类的所有构造函数中的第一行,其实都有一条隐身的语句super(); 为什么子类对象初始化时,都需要调用父类中的函数?(为什么要在子类构造函数的第一行加入这个super()?) 因为子类继承父类,会继承到父类中的数据,所以必须要看父类是如何对自己的数据进行初始化的。所以子类在进行对象初始化时,先调用父类的构造函数,这就是子类的实例化过程。 注意: 如果子类构造函数中用this来指定调用子类自己的构造函数,那么被调用的构造函数也一样会访问父类中的构造函数。 问题:super()和this()是否可以同时出现的构造函数中。 两个语句只能有一个定义在第一行,所以只能出现其中一个。 super()或者this():为什么一定要定义在第一行? 因为super()或者this()都是调用构造函数,构造函数用于初始化,所以初始化的动作要先完成。 继承的细节: 什么时候使用继承呢? 当类与类之间存在着所属关系时,才具备了继承的前提。a是b中的一种。a继承b。狼是犬科中的一种。 英文书中,所属关系:" is a " 注意:不要仅仅为了获取其他类中的已有成员进行继承。 所以判断所属关系,可以简单看,如果继承后,被继承的类中的功能,都可以被该子类所具备,那么继承成立。如果不是,不可以继承。 在方法覆盖时,注意两点: 1:子类覆盖父类时,必须要保证,子类方法的权限必须大于等于父类方法权限可以实现继承。否则,编译失败。 2:覆盖时,要么都静态,要么都不静态。 (静态只能覆盖静态,或者被静态覆盖) 继承的一个弊端:打破了封装性。对于一些类,或者类中功能,是需要被继承,或者复写的。 这时如何解决问题呢?介绍一个关键字,final:最终。 3.final 1:这个关键字是一个修饰符,可以修饰类,方法,变量。 2:被final修饰的类是一个最终类,不可以被继承。 3:被final修饰的方法是一个最终方法,不可以被覆盖。 4:被final修饰的变量是一个常量,只能赋值一次。 5.内部类只能访问被final修饰的局部变量。 其实这样的原因的就是给一些固定的数据起个阅读性较强的名称。 不加final修饰不是也可以使用吗?那么这个值是一个变量,是可以更改的。加了final,程序更为严谨。常量名称定义时,有规范,所有字母都大写,如果由多个单词组成,中间用 _ 连接。 4.抽象类:abstract 概念:抽象就是从多个事物中将共性的,本质的内容抽取出来。 例如:狼和狗共性都是犬科,犬科就是抽象出来的概念。 Java中可以定义没有方法体的方法,该方法的具体实现由子类完成,该方法称为抽象方法,包含抽象方法的类就是抽象类。 抽象方法的由来: 多个对象都具备相同的功能,但是功能具体内容有所不同,那么在抽取过程中,只抽取了功能定义,并未抽取功能主体,那么只有功能声明,没有功能主体的方法称为抽象方法。 例如:狼和狗都有吼叫的方法,可是吼叫内容是不一样的。所以抽象出来的犬科虽然有吼叫功能,但是并不明确吼叫的细节。 4.1抽象类的特点 |-- 被abstract修饰的方法,称为抽象方法,不能有方法体,不要写大括号 |-- 抽象方法,必须存在于抽象类中,类也需要abstract修饰 |-- 不可以实例化,不能建立对象 不可以 new 抽象类是具体事物抽取出来的,本身是不具体的,没有对应的实例。例如:犬科是一个抽象的概念,真正存在的是狼和狗。而且抽象类即使创建了对象,调用抽象方法也没有意义。 |-- 抽象类通过其子类实例化,定义子类,继承抽象类,覆盖所有抽象方法,建立子类对象。如果子类覆盖了部分抽象方法,这个子类还是抽象类 |-- 抽象类,可以存在普通方法的,也可以没有抽象方法这样做仅仅是不让该类建立对象。 |-- 抽象类,有构造方法的,可以为子类赋值操作,参考程序员和经理的案例***** 抽象关键字abstract不可以和哪些关键字共存? final:被final修饰的类不能有子类。而被abstract修饰的类一定是一个父类。 private: 抽象类中的私有的抽象方法,不被子类所知,就无法被复写。 而抽象方法出现的就是需要被复写。 static:如果static可以修饰抽象方法,那么连对象都省了,直接类名调用就可以了。 可是抽象方法运行没意义。 练习:Abstract
/* 假如我们在开发一个系统时需要对员工进行建模,员工包含 3 个属性: 姓名、工号以及工资。经理也是员工,除了含有员工的属性外,另为还有一个 奖金属性。请使用继承的思想设计出员工类和经理类。要求类中提供必要的方 法进行属性访问。 员工类:name id pay 经理类:继承了员工,并有自己特有的bonus。 */ abstract class Emplyee { private String name; private String id; private Double pay; Emplyee(Stringname,String id,Double pay) { this.name= name; this.id= id; this.pay= pay; } public abstract void work(); } class Manager extends Emplyee { private int bouns; Manager(Stringname,String id,Double pay,int bonus) { super(name,id,pay); this.bouns= bouns; } public void work() { System.out.println("Managerwork"); } } class Pro extends Emplyee { Pro(Stringname,String id,Double pay) { super(name,id,pay); } public void work() { System.out.println("Prowork"); } } class AbstractDemo { public static void main(String[] args) { Managerm = new Manager("张三","001",12000.00,5000); m.work(); Prop1 = new Pro("李四","022",8000.00); p1.work(); } }
4.2模板方法设计模式:
在定义功能时,功能的一部分是确定的,但是有一部分是不确定,而确定的部分在使用不确定的部分,那么这时就将不确定的部分暴露出去。由该类的子类去完成。
练习:获取一段程序运行的时间 Abstract+Final的应用
/* 需求:获取一段程序运行的时间。 原理:获取程序开始和结束的时间并相减即可。 获取时间:System.currentTimeMillis(); 当代码完成优化后,就可以解决这类问题。 这种方式,模版方法设计模式。 */ abstract class GetTime { public final void getTime() //final修饰下,不让其他子类复写 { long start = System.currentTimeMillis(); run Code(); //不确定的功能部分,提取出来,通过抽象方法实现 long end = System.currentTimeMillis(); System.out.println("耗时:"+(end-start)); } public abstract void runCode(); //抽象不确定的功能,让子类复写实现 } class RunCode extends GetTime { public void runCode() { for(int x=0; x<4000; x++) { System.out.print(x); } } } class GetTimeDemo { public static void main(String[] args) { Run Codegt = new RunCode(); gt.getTime(); } }
接口
接口就是对外暴露的规则;是程序的功能扩展
初期理解,可以认为是一个特殊的抽象类
当抽象类中的方法都是抽象的,那么该类可以通过接口的形式来表示。
定义接口:interface 接口名
接口中的成员修饰符是固定的。
成员常量:public static final int X = 20;
成员函数:public abstract void show();
接口中权限必须是 最大的public
接口的出现将“多继承”通过另一种形式体现出来,即“多实现”
5.1接口特点
|-- 成员都是由固定格式,修饰符写不写也有!!
|-- 权限必须是public 最大权限
|-- 接口中的方法全部都是抽象的
|-- 子类(实现类) implements接口,并覆盖接口中全部的抽象方法,建立子类的对象
接口可以被多实现。一个子类,在继承一个类的同时,可以实现多个接口
如;class ABImpl extends C implements A,B
如果A,B这两个接口,有一样的抽象方法,没有主体。子类覆盖说了算
5.2接口的使用
1. 接口不能建立对象 new 接口
2. 定义子类 实现接口,并覆盖接口中的全部抽象方法,建立子类的对象
class 子类 implements 接口{
覆盖抽象方法
}
3. 如果子类只覆盖了部分抽象方法,子类还是一个抽象类
4. 子类看做是这个接口的实现类,先期理解为继承,接口看做是子类的父类
5.3 java中支持多继承吗
类与类之间是继承关系 extends
类和接口之间是实现关系 implements
接口与接口之间是继承关系 extends
接口之间支持多继承,一个接口同时继承多个接口
问java中支持多继承吗?
类与类之间不支持,接口之间支持多继承
5.4继承extends和实现implements的区别
1. 继承的单继承
2. 可以多实现
3. 继承后,父类的方法可以被子类直接使用
4. 实现后,必须覆盖抽象方法,才可以使用子类
5. 多实现的出现,避免了单继承的局限性
5.5抽象类abstrct class和接口interface的区别
1. 抽象类可以有非抽象的方法(普通方法);接口全部都是抽象方法
2. 接口中的成员都是固定的 final
3. 抽象类的成员修饰符可以自定义。
接口中的成员修饰符是固定的。全都是public的。
4. 抽象类被子类继承可以直接使用非抽象方法
接口必须实现后覆盖全部的抽象方法
5. 抽象类是这个继承体系的最共性内容 子类是之间是一个 is a关系
接口是这个体系外的扩展功能,实现类之间是一个 like a关系
猫继承自哺乳动物
基础班是传智播客的一个班级,看起来也像一个烟民。
5.6接口的好处
接口就是对外暴露的规则;是程序的功能扩展
1.接口的出现降低耦合性
2.接口可以用来多实现。避免了单继承的局限
6.多态
就是父类或者接口的引用指向自己的子类对象 //Animal a = new Cat();
目的:是为了扩展程序,无限的增加子类,只要子类重写了方法
Fu f = new Zi(); f.方法(); 子类重写
好处:提高了程序的扩展性
弊端:只能调用子类重写的方法,不能调用子类特有的方法
如果想用子类对象的特有方法,先通过instanceof判断对象是哪个具体的子类类型,再强制向下转型
关键字 instanceof //判断对象是否实现了指定的接口或继承了指定的类
前提: 必须要有关系,比如继承、或者实现。
通常会有覆盖操作。
多态的出现思想上也做着变化:
以前是创建对象并指挥对象做事情。有了多态以后,我们可以找到对象的共性类型,直接操作共性类型做事情即可,这样可以指挥一批对象做事情,即通过操作父类或接口实现。
多态中成员特点:
非静态成员方法 编译看左边,运行看右边
其他的编译和运行全看左边
/* 需求: 电脑运行实例, 电脑运行基于主板。 */ interface PCI { public void open(); public void close(); } class MainBoard { public void run() { System.out.println("mainboardrun "); } public void usePCI(PCI p)//PCI p = new NetCard()//接口型引用指向自己的子类对象。 { if(p!=null) { p.open(); p.close(); } } } class NetCard implements PCI { public void open() { System.out.println("netcardopen"); } public void close() { System.out.println("netcardclose"); method(); } } class SoundCard implements PCI { public void open() { System.out.println("SoundCardopen"); } public void close() { System.out.println("SoundCardclose"); } } class DuoTaiDemo { public static void main(String[] args) { MainBoard mb = new MainBoard(); mb.run(); mb.usePCI(null); mb.usePCI(newNetCard()); mb.usePCI(newSoundCard()); } }
----------------------- android培训、java培训、java学习型技术博客、期待与您交流! ----------------------
相关文章推荐
- 黑马程序员---【OC语言】03面向对象之封装
- 黑马程序员-面向对象03
- 黑马程序员_Java基础_面向对象_03
- 黑马程序员--Java基础--03面向对象(1)
- 黑马程序员——OC学习笔记03 面向对象2 面向对象的三大特性
- 黑马程序员——Java语言基础——03.面向对象(2)三大特征
- 黑马程序员_<<面向对象(多态)---03>>
- 黑马程序员--面向对象的三大基本特征(继承)(03)
- 黑马程序员-Java面向对象4
- 黑马程序员—JAVA面向对象的特征
- 黑马程序员——面向对象
- 黑马程序员--03.Java面向对象--01.【OOP基本概念】【匿名对象】【封装】【构造函数】【this关键字】
- 黑马程序员——Java语言基础——03.面向对象(3)异常
- 黑马程序员--Objective-C语言基础知识--面向对象
- 黑马程序员—【Java基础篇】之面向对象
- 黑马程序员——Java基础语法 之面向对象(概念,特征,this,static关键字,代码块)
- 黑马程序员 Java面向对象——交通灯管理系统
- 黑马程序员_面向对象(2) 接口&抽象类&内部类
- 黑马程序员---java基础之面向对象(一)三大特征(封装,继承,多态)
- 黑马程序员---面向对象的多态性