黑马程序员——Java基础知识——面向对象(二)
来源:互联网 发布:美萍软件介绍 编辑:程序博客网 时间:2024/06/04 23:32
------Java培训、Android培训、iOS培训、.Net培训、期待与您交流!
一、继承
什么是继承:
面向对象的一个重要特征,在以后的操作中会经常使用。当多个类中存在相同属性或行为时,将这些相同的内容抽取到单独一个类中,那么多个类无需再定义这 些属性和行为,只要继承这个类即可。那个单独的类称之为父类,其他的类就是子类。例如工人和学生都可以向上抽取出人这个父类,在父类中定义姓名、年龄等属 性,然后通过继承,工人和学生也具备了这种属性。在代码中通过extends表示继承关系。当类与类之间有了继承的关系,子类可以直接访问父类中的非私有的属性 和行为。继 承的出现提高了代码的复用性。让类和类之间产生了关系,有了这个关系,提供了多态的前提。在Java语言中,只支持单继承,不支持多继承,但Java 中有另一种体现 方式,叫多实现,在以后会学习到。注意,当类与类之间有所属关系时才可以继承。这种所属关系称为is a.
如何使用继承:
Java中可以多层继承,就是建立一个继承体系,如同爷爷、父亲和孩子的关系,例如:
class A{}
class B extendsA{}
class C extendsB{}
当要使用一个继承体系中所具备的功能时,要先查体系中父类的描述,因为父类中定义的是该体系中的共性功能。通过了解共性功能,就可以知道该体系中的 基本功能。这样这个体系就可以基本使用了;而在具体调用时,要创建最子类的对象,因为父类可能无法创建对象,而子类对象中又有更多的功能,除了基本功能外 还有其特有的。总结为一句话就是:查阅父类功能,创建子类对象使用功能。
例如:
class Person{ //在父类中定义都共同具有的姓名、年龄属性以及睡觉的方法。 String name; int age; public void sleep(){ System.out.println("sleep");}}class Worker extends Person{ //因为继承父类,也具备父类的属性以及睡觉的方法,并定义工人特有的方法 public void work(){ System.out.println("work");}}class Student extends Person{ //因为继承父类,也具备的属性以及睡觉的方法,并定义学生特有的方法 public void study(){ System.out.println("study");}}
3.继承中成员的特点
(1)成员变量:如果子类中出现非私有的同名成员变量时,子类访问本类中的变量,用this,访问父类中的同名变量,则要用super。super和this都存在于方法 区中,使用方法相似。this表示本类的引用,super表示父类的引用。
(2)成员方法:当子类和父类有一模一样的方法时,当子类对象调用该方法,会运行子类方法的内容,如同父类的方法被覆盖,这种情况称为:重写(覆盖)。
当子类继承父类,沿袭了父类的方法,在子类中方法的内容却与父类不同,这时就可以用到重写,保留父类的方法定义,重写方法内容。子类的方法中同时具有父类
方法中的内容时,可以用super.方法。例如:
class Person{ public void sleep(){ System.out.println("sleep"); }}class Worker extends Person{ //复写父类方法 public void sleep(){ System.out.println(" earlier to sleep"); }}class Student extends Person{ //复写父类方法,并调用父类方法。 public void sleep(){ super.sleep(); System.out.println("第二天早起读书"); }}要注意几点:子类要覆盖父类,必须保证子类权限大于或等于父类权限,才可以覆盖,否则编译失败;静态只能覆盖静态;父类中的私有方法不能被重写。
(3)构造函数
在对子类对象进行初始化时,父类的构造函数也会运行,因为子类的每一个构造函数默认的第一行都有一条隐式的super()。通过super()语句,会访问父类中空 参数的构造函数。子类对象在初始化时一定要访问父类中的构造函数,是因为父类中的数据子类可以直接获取,所以子类对象在建立时,需要先查看父类是如何对这 些数据进行初始化的。所以子类在对象初始化时,要先访问父类中的构造函数。如果要访问父类中非空参数的构造函数,需要通过定义super语句来指定,同this语句 一样,super语句也必须定义在构造函数中的第一行。子类的构造函数第一行也可以定义this语句来访问本类中的构造函数。总之,子类中至少会有一个构造函数访问 父类中的构造函数。
final关键字
final(最终),作为一个修饰符。具有以下特点:
1、可以修饰类、函数、变量。
2、被final修饰的类不可以被继承。这样就可以避免被继承、被子类复写功能。
3、被final修饰的方法不可以被覆盖。
4、被final修饰的变量是一个常量只能赋值一次,既可以修饰成员变量,又可以修饰局部变量。
当在描述事物时,一些数据的出现值是固定的,那么这时为了增强阅读性,都给这些值起个名字。方便于阅读。而这个值不需要改变,所以加上final修饰。作为常量:常量的书写规范所有字母都大写,如果由多个单词组成,单词间通过_连接。
5、内部类定义在类中的局部位置上时,只能访问该局部被final修饰的局部变量。
二、抽象类
多个类中出现相同功能,但功能具体内容不同,那么在抽取过程中,只抽取了功能定义,并没抽取功能主体,那么只有功能声明,没有功能主体的方位称为抽 象方法。抽象方法没有方法主体,方法的具体实现由该类的子类去完成。包含抽象方法的类叫做抽象类。例如:
abstract class Person{//定义表示睡觉的抽象方法public abstract void sleep();}class Worker extends Person{//工人睡觉的具体方法public void sleep(){ System.out.println("早睡");}}class Student extends Person{//学生睡觉的具体方法public void sleep(){ System.out.println("晚睡");}}从上面的代码可以看出,抽象类和抽象方法都必须用abstract修饰。抽象方法定义在抽象类中,但同时抽象类中也可以有非抽象方法,抽象方法没有方法主体,只 有方法声明。抽象类不可以被创建对象,因为调 用抽象方法没有意义。抽象类中的抽象方法要被使用,必须由子类覆盖抽象类中的所有抽象方法,然后建立子类对象 调用,否则子类还是抽象类。
抽象类与一般类相比,没有太大的不同,都是描述事物,只不过该事物中出现了一些不知道具体内容的方法部分。这些不确定的部分,也是该事物的功 能,需要明确出来,但是无法定义主体。通过抽象方法表示;抽象类比一般类多了一个或多个抽象函数,并且不可以被实例化;抽象类虽然不能创建对 象,但是也有构造函数,供子类实例化调用。
注意的是,抽象类中也可以没有抽象函数,这样做是为了不让建立该类的对象。在使用abstract关键字修饰方法和类时,不能同时使用private、final、 static进行修饰。因为final修饰的类不能被继承,而抽象类是一个父类;private修饰的方法不能被复写,而抽象方法必须被复写;static修饰的方法,不需要 对象调用,而抽象方法运行没有意义。
下面就通过一段代码,说明抽象类的使用。如下:
/**需求:开发一个系统时需要对员工进行建模,员工包含3个属性:姓名、工号以及工资。 经理也是员工,除了含有员工的属性外,另为还有一个奖金属性。请使用继承的思 想设计出员工类和经理类。员工类:name id pay经理类:继承了员工,并有自己特有的bonus。*///定义员工类,定义所有公司成员的共同属性和方法class Employee{//定义共同的姓名、工号、工资的属性private String name;private String id;private double pay;Employee(String name,String id,double pay){this.name = name;this.id = id;this.pay = pay;}//定义工作的抽象方法,工作内容由员工根据工作范围自己去实现。public abstract void work();}class Manager extends Employee{ //定义经理类特有的奖金属性private int bonus;Manager(String name,String id,double pay,int bonus){ super(name,id,pay);this.bonus = bonus;}//经理的具体工作内容public void work(){System.out.println("manager work");}}class Pro extends Employee{Pro(String name,String id,double pay){super(name,id,pay);}//普通员工的具体工作内容public void work(){System.out.println("pro work");}}模板方法:在定义功能时,功能的一部分是确定,但是有一部分是不确定的,而确定的部分在使用不确定的部分,那么这时就将不确定的部分暴露出去。由该类的 的子类去完成。如果不确定的方法没有默认的方法主体,就用抽象方法表示,然后由子类去复写。例如:
/**需求:获取一段程序运行的时间。原理:获取程序开始和结束的时间并相减即可。*/abstract class GetTime{ public final void getTime(){//表示程序开始时的时间long start = System.currentTimeMillis();runProgram();//表示程序结束时的时间long end = System.currentTimeMillis();System.out.println("毫秒:"+(end-start));}//具体程序未知,用抽象方法表示public abstract void runProgram();}class SubTime extends GetTime{ //定义具体的运行程序 public void runProgram(){ for(int x=0; x<3000; x++){System.out.print(x);}}}
三、接口
可以理解为一个特殊的抽象类,但接口中的方法都是抽象的。当一个类中所有的方法都是抽象时就可以用接口来表示,接口用interface关键字来表示,而子类与接口通过implements(实现)产生关系,并必须覆盖其所有抽象方法,才能创建子类对象,否则该类是个抽象类。接口中常见的定义是常量和抽象方法。两者都有固定的修饰符,常量:public static final ;方法:public abstract;也可以在常量和方法前不写这些修饰符,编译时会自动添加,但为了提高阅读性,一般时候都加上。下面通过一段简单的代码,了解一下接口及其子类的格式,如下:
//定义一个类表示男子的接口interface Man{//定义性别属性,常量用大写字母表示public static final String SEX="man";//定义表示工作的抽象方法public abstract void work();}//定义一个类表示年轻男子,实现Man接口class YoungMan implements Man{ //覆盖接口中的抽象方法 public void work() { System.out.println("工作时间长"); }}接口是对外暴露的规则,接口的出现降低了耦合性,能对程序的功能进行扩展;类与接口是实现关系,java支持多实现,一个类可以继承一个类的同时 实现多个接口; 而接口和接口之间是继承关系。在使用接口时要注意,子类需覆盖接口中的所有抽象方法,否则子类还是个抽象类;当一个类实现多个接口时,多个接口中不能有返回值类型不同的同名抽象函数,这样子类无法实现复写。
接口与抽象类都是由下向上抽取出来的。但两者又有很多区别:抽象类体检继承关系,父类与子类是"is a"的关系,一个类只能继承一个抽象类,而接口体现实现关系,接口与子类是"like a"关系,一个类可以实现多个接口;抽象类中可以定义非抽象方法,子类可以直接使用,类中可以定义私有变量和方法。而接口中所有的方法都是抽象的,并且所有成员都有固定的修饰符,所有成员的权限都是公有的;下面看一个接口与抽象类都有应用的程序,例如:
//定义一个抽象类,表示人 abstract class Person { //定义抽象的饮食方法 abstract void eat(); //定义共同的睡觉方法 void sleep() { System.out.println("sleep"); } } //定义一个接口,表示训练 interface Training{ public abstract void train(); } //定义表示运动员的Athlete类,继承Person类,实现训练接口 class Athlete extends Person implements Training { //复写饮食方法 void eat() { System.out.println("多吃牛肉"); } //复写训练方法 public void train() { System.out.println("每天都要训练"); } } //定义表示学生的Student的类,不训练class Student extends Person { //复写饮食方法 void eat() { System.out.println("多吃蔬菜"); } }
-------------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------
- 黑马程序员—java面向对象二
- 黑马程序员——面向对象基础知识
- 黑马程序员——java基础面向对象基础知识总结
- 黑马程序员——Java基础知识——面向对象(二)
- 黑马程序员——java基础知识之面向对象(二)
- 黑马程序员——JAVA面向对象(二)
- 黑马程序员——Java面向对象(二)
- 黑马程序员——java基础---面向对象(二)
- 黑马程序员——Java面向对象(二)
- 黑马程序员——Java面向对象知识点(二)
- 黑马程序员——JAVA 面向对象总结(二)
- 黑马程序员——Java基础---面向对象(二)
- 黑马程序员——Java基础---面向对象<二>
- 黑马程序员——java基础-面向对象(二)
- 黑马程序员——JAVA之面向对象(二)
- 黑马程序员——Java语言--面向对象(二)
- 黑马程序员——Java基础-------面向对象(二)
- 黑马程序员——Java基础---面向对象(二)
- 面试题4——求一个int型整数的两种递减数之和
- 我的java学习笔记(5)关于对象构造
- [****Camp Day 1]C. Control Point(乱搞)
- 安装Sublime Text 3插件的方法
- OJ 1185 特殊排序
- 黑马程序员——Java基础知识——面向对象(二)
- Hadoop学习笔记之Hadoop简介
- 面向对象学习(4)
- 利用旋转矩阵简便旋转二位矢量(SDacm4A题解)
- web项目中导入外部jar
- Android图像处理技术(实现Android中的PS)(四)
- android 仓库下载分析
- arm-linux-gcc安装和配置
- C语言不支持引用传递和函数重载