java学习笔记7--抽象类与抽象方法
接着前面的学习:
java学习笔记6--类的继承、Object类
java学习笔记5--类的方法
java学习笔记4--类与对象的基本概念(2)
java学习笔记3--类与对象的基本概念(1)
java学习笔记2--数据类型、数组
java学习笔记1--开发环境平台总结
本文地址:http://www.cnblogs.com/archimedes/p/java-study-note7.html,转载请注明源地址。
1、终结类与终结方法
被final修饰符修饰的类和方法,终结类不能被继承,终结方法不能被当前类的子类重写
终结类的特点:不能有派生类
终结类存在的理由:
安全: 黑客用来搅乱系统的一个手法是建立一个类的派生类,然后用他们的类代替原来的类
设计: 你认为你的类是最好的或从概念上你的类不应该有任何派生类
终结方法的特点:不能被派生类覆盖
终结方法存在的理由:
对于一些比较重要且不希望子类进行更改的方法,可以声明为终结方法。可防止子类对父类关键方法的错误重写,增加了代码的安全性和正确性
提高运行效率。通常,当java运行环境(如java解释器)运行方法时,它将首先在当前类中查找该方法,接下来在其超类中查找,并一直沿类层次向上查找,直到找到该方法为止
final 方法举例:
class Parent {public Parent() { } //构造方法final int getPI() { return Math.PI; } //终结方法 }
说明: getPI()是用final修饰符声明的终结方法,不能在子类中对该方法进行重载
2、抽象类
抽象类:代表一个抽象概念的类
没有具体实例对象的类,不能使用new方法进行实例化
类前需加修饰符abstract
可包含常规类能够包含的任何东西,例如构造方法,非抽象方法
也可包含抽象方法,这种方法只有方法的声明,而没有方法的实现
抽象类是类层次中较高层次的概括,抽象类的作用是让其他类来继承它的抽象化的特征
抽象类中可以包括被它的所有子类共享的公共行为
抽象类可以包括被它的所有子类共享的公共属性
在程序中不能用抽象类作为模板来创建对象;
在用户生成实例时强迫用户生成更具体的实例,保证代码的安全性
举个例子:
将所有图形的公共属性及方法抽象到抽象类Shape。再将2D及3D对象的特性分别抽取出来,形成两个抽象类TwoDimensionalShape及ThreeDimensionalShape
–2D图形包括Circles、Triangles、Rectangles和Squares
–3D图形包括Cube、Sphere、或Tetrahedron
–在UML中,抽象类的类名为斜体,以与具体类相区别:
抽象类声明的语法形式为
abstract class Number {. . . }
3、抽象方法
声明的语法形式为:
public abstract <returnType> <methodName>(...);
仅有方法头,而没有方法体和操作实现,具体实现由当前类的不同子类在它们各自的类声明中完成,抽象类可以包含抽象方法
需注意的问题:
一个抽象类的子类如果不是抽象类,则它必须为父类中的所有抽象方法书写方法体,即重写父类中的所有抽象方法
只有抽象类才能具有抽象方法,即如果一个类中含有抽象方法,则必须将这个类声明为抽象类
- 除了抽象方法,抽象类中还可以包括非抽象方法
抽象方法的优点:
隐藏具体的细节信息,所有的子类使用的都是相同的方法头,其中包含了调用该方法时需要了解的全部信息
强迫子类完成指定的行为,规定其子类需要用到的“标准”行为
举一个绘图的例子:
各种图形都需要实现绘图方法,可在它们的抽象父类中声明一个draw抽象方法
abstract class GraphicObject {int x, y;void moveTo(int newX, int newY) { . . . }abstract void draw(); }
然后在每一个子类中重写draw方法,例如:
class Circle extends GraphicObject {void draw() { . . . } } class Rectangle extends GraphicObject {void draw() { . . . } }
举一个例子:
首先定义一个抽象类:
abstract class Person {private String name; //具体数据public Person(String n) { //构造函数name = n;}public String getName() { //具体方法return name;}public abstract String getDescription(); //抽象方法 }
下面通过抽象类Person扩展一个具体子类Student:
class Student extends Person {private String major;public Student(String n, String m) {super(n);major = m;}public String getDescription() { //实现抽象类中的getDescription方法return "a student majoring in " + major;} }
通过抽象类Person扩展一个具体子类Employee:
class Employee extends Person {private double salary;private Date hireDay;public Employee(String n, double s, int year, int month, int day) {super(n);salary = s;GregorianCalendar calendar = new GregorianCalendar(year, month - 1, day);hireDay = calendar.getTime();}public double getSalary() {return salary;}public Date getDate() {return hireDay;}public String getDescription() { //实现抽象类中的getDescription方法return String.format("an employee with a salary of $%.2f", salary);}public void raiseSalary(double byPercent) {double raise = salary * byPercent / 100;salary += raise;} }
测试程序如下:
public class javatest {public static void main(String[] args) {Person[] people = new Person[2]; people[0] = new Employee("Hary Hacker", 50000, 1989, 10, 1);people[1] = new Student("Maria Morris", "Computer science");for(Person p : people)System.out.println(p.getName() + ", " + p.getDescription());} }
运行结果如下:
Hary Hacker, an employee with a salary of $50000.00
Maria Morris, a student majoring in Computer science
再举一个例子:
先定义一个几何抽象类GeometricObject:
import java.util.*; public abstract class GeometricObject {private String color = "write";private boolean filled;private Date dateCreated;//构造函数(protected类型)protected GeometricObject() {dateCreated = new Date();}protected GeometricObject(String color, boolean filled) {dateCreated = new Date();this.filled = filled;this.color = color;}public String getColor() {return color;}public void setColor(String color) {this.color = color;}public boolean isFilled() {return filled;}public void setFilled(boolean filled) {this.filled = filled;}public Date getDateCreated() {return dateCreated;}public String toString() {return "created on" + dateCreated + "\ncolor: " + color + " and filled: " + filled;}public abstract double getArea(); //抽象方法public abstract double getPerimeter(); //抽象方法 }
定义一个具体类Circle继承抽象类:
public class Circle extends GeometricObject{private double radius;public Circle() {}public Circle(double radius) {this.radius = radius;}public Circle(double radius, String color, boolean filled) {this.radius = radius;setColor(color); //继承基类setFilled(filled); //继承基类 }public double getRadius() {return radius;}public void setRadius(double radius) {this.radius = radius;}public double getArea() { //实现抽象类中的抽象方法getArea()return radius * radius * Math.PI;}public double getPerimeter() { //实现抽象类中的抽象方法getPerimeter()return radius * 2 * Math.PI;}}
定义一个具体类Rectangle继承抽象类:
public class Rectangle extends GeometricObject {private double width;private double heigth;public Rectangle() {}public Rectangle(double width, double heigth) {this.width = width;this.heigth = heigth;}public Rectangle(double width, double heigth, String color, boolean filled) {this.width = width;this.heigth = heigth;setColor(color);setFilled(filled);}public double getWidth() {return width;}public void setWidth(double width) {this.width = width;}public double getHeigth() {return heigth;}public void setHeigth(double heigth) {this.heigth = heigth;}public double getArea() {return width * heigth;}public double getPerimeter() {return 2 * (width + heigth);} }
3、类的组合
面向对象编程的一个重要思想就是用软件对象来模仿现实世界的对象,现实世界中,大多数对象由更小的对象组成
与现实世界的对象一样,软件中的对象也常常是由更小的对象组成,Java的类中可以有其他类的对象作为成员,这便是类的组合
组合的语法很简单,只要把已存在类的对象放到新类中即可,可以使用“has a”语句来描述这种关系
例如,考虑Kitchen类提供烹饪和冷藏食品的功能,很自然的说“my kitchen 'has a' cooker/refrigerator”。所以,可简单的把对象myCooker和myRefrigerator放在类Kitchen中。格式如下:
class Cooker{ // 类的语句 } class Refrigerator{ // 类的语句} class Kitchen{ Cooker myCooker;Refrigerator myRefrigerator; }
一条线段包含两个端点:
public class Point //点类 {private int x, y; //coordinatepublic Point(int x, int y) { this.x = x; this.y = y;}public int GetX() { return x; }public int GetY() { return y; } } class Line //线段类 {private Point p1,p2; // 两端点 Line(Point a, Point b) { p1 = new Point(a.GetX(),a.GetY());p2 = new Point(b.GetX(),b.GetY());}public double Length() { return Math.sqrt(Math.pow(p2.GetX()-p1.GetX(),2) + Math.pow(p2.GetY()-p1.GetY(),2));} }
组合与继承的比较:
“包含”关系用组合来表达
如果想利用新类内部一个现有类的特性,而不想使用它的接口,通常应选择组合,我们需在新类里嵌入现有类的private对象
如果想让类用户直接访问新类的组合成分,需要将成员对象的属性变为public
“属于”关系用继承来表达
取得一个现成的类,并制作它的一个特殊版本。通常,这意味着我们准备使用一个常规用途的类,并根据特定需求对其进行定制
举个例子:
car(汽车)对象是一个很好的例子,由于汽车的装配是故障分析时需要考虑的一项因素,所以有助于客户程序员理解如何使用类,而且类创建者的编程复杂程度也会大幅度降低
class Engine { //发动机类public void start() {}public void rev() {}public void stop() {} } class Wheel { //车轮类 public void inflate(int psi) {} } class Window { //车窗类public void rollup() {}public void rolldown() {} } class Door { //车门类public Window window = new Window();public void open() {}public void close() {} } public class Car {public Engine engine = new Engine();public Wheel[] wheel = new Wheel[4];public Door left = new Door(),right = new Door(); public Car() {for(int i = 0; i < 4; i++)wheel[i] = new Wheel();}public static void main(String[] args) {Car car = new Car();car.left.window.rollup();Car.wheel[0].inflate(72);} }
许多时候都要求将组合与继承两种技术结合起来使用,创建一个更复杂的类
举个例子(组合与继承举例):
class Plate { //声明盘子public Plate(int i) {System.out.println("Plate constructor");} } class DinnerPlate extends Plate { //声明餐盘为盘子的子类public DinnerPlate(int i) {super(i);System.out.println("DinnerPlate constructor");} } class Utensil { //声明器具Utensil(int i) {System.out.println("Utensil constructor");} } class Spoon extends Utensil { //声明勺子为器具的子类public Spoon(int i) {super(i);System.out.println("Spoon constructor");} } class Fork extends Utensil { //声明餐叉为器具的子类public Fork(int i) {super(i);System.out.println("Fork constructor");} } class Knife extends Utensil { //声明餐刀为器具的子类public Knife(int i) {super(i);System.out.println("Knife constructor");} } class Custom { // 声明做某事的习惯public Custom(int i) { System.out.println("Custom constructor");} } public class PlaceSetting extends Custom {//声明餐桌的布置 Spoon sp; Fork frk; Knife kn; DinnerPlate pl;public PlaceSetting(int i) {super(i + 1);sp = new Spoon(i + 2);frk = new Fork(i + 3);kn = new Knife(i + 4);pl = new DinnerPlate(i + 5);System.out.println("PlaceSetting constructor");}public static void main(String[] args) {PlaceSetting x = new PlaceSetting(9);} }
运行结果:
Custom constructor
Utensil constructor
Spoon constructor
Utensil constructor
Fork constructor
Utensil constructor
Knife constructor
Plate constructor
DinnerPlate constructor
PlaceSetting constructor
参考资料:
《java程序设计》--清华大学
java学习笔记7--抽象类与抽象方法相关推荐
- JAVA学习笔记之抽象类与接口2020-3-22
抽象类 先了解一下抽象类的概念. 一个完整的方法,是有: 1.方法声明 2.方法体 public void show(){方法体; } 而如果只包含方法声明,没有方法体,那么就称之为:抽象方法.(ab ...
- 【Java 学习笔记】 抽象类和接口
抽象类:类的设计应当保证父类包含子类的共同特征,有时为了方便会将父类设计的特别抽象以至于没有具体实例,称之为抽象类. -多重继承:需要从多个类中派生出一个子类,这种能力叫做多重继承. -单重继承:每个 ...
- java学习笔记day09 final、多态、抽象类、接口
java学习笔记day09 思维导图 final . 多态 . 抽象类 . 接口 (都很重要) 一.final 二.多态 多态中的成员访问特点⭐ [P237] 多态的好处 [P239] 多态的弊端 向 ...
- java学习笔记16--I/O流和文件
本文地址:http://www.cnblogs.com/archimedes/p/java-study-note16.html,转载请注明源地址. IO(Input Output)流 IO流用来处理 ...
- java学习笔记9--内部类总结
java学习笔记系列: java学习笔记8--接口总结 java学习笔记7--抽象类与抽象方法 java学习笔记6--类的继承.Object类 java学习笔记5--类的方法 java学习笔记4--对 ...
- java学习笔记8--接口总结
接着前面的学习: java学习笔记7--抽象类与抽象方法 java学习笔记6--类的继承.Object类 java学习笔记5--类的方法 java学习笔记4--对象的初始化与回收 java学习笔记3- ...
- 【Java学习笔记之二十六】深入理解Java匿名内部类
在[Java学习笔记之二十五]初步认知Java内部类中对匿名内部类做了一个简单的介绍,但是内部类还存在很多其他细节问题,所以就衍生出这篇博客.在这篇博客中你可以了解到匿名内部类的使用.匿名内部类要注意 ...
- Java学习笔记之基础篇
Java学习笔记之基础篇 目录 Java如何体现平台的无关性? 面向对象(OO)的理解 面向对象和面向过程编程的区别 面向对象三大特征 静态绑定和动态绑定(后期绑定) 延伸:类之间的关系 组合(聚合) ...
- 郑志远的java学习笔记
郑志远的java学习笔记 郑志远 CCB 1 Java起源 略 2 Java语言概述 1.面向对象编程的3个原则:封装(encapsulation).继承(inh ...
最新文章
- Python 实现九九乘法表
- linux 下 php 安装 Gearman
- pd16.5生成mysql列说明_PowerDesigner16逆向工程生成PDM列注释(My Sql5.0模版)
- 浅析一般网站建设的需要耗费多长时间?
- 从你输入一个网址,到网页显示,其间发生了什么?
- java入参为方法_Java命令注入原理结合Java Instrument技术(FreeBuf首发)
- C#.net调用Excel出现问题
- java多条件组合查询6_elasticsearch组合多条件查询实现restful api以及java代码实现
- spring5高级编程_Spring 5.X系列教程:满足你对Spring5的一切想象-持续更新
- (算法)宝石升级问题
- Java8新特性总结 -6.Date/Time API
- dijkstra 最短路算法
- Android Gradle进阶配置指南
- SCOM 2007 R2监控系统安装部署(一)SCOM简介及安装SQL Server 2008 R2 数据库
- 20个优秀的 HTML5 网站设计案例欣赏
- 目标识别—SSD网络详解
- python日常实用技能:使用python将大量数据导出到Excel中的
- 修改PPT输出JPG图片分辨率为300 dpi
- 宝塔linux如何防护,使用宝塔面板的CC***防护策略
- 关于MyBatis的分页