【连载】Java学习系列(007)——继承和多态
来源:互联网 发布:支付系统网络硬件架构 编辑:程序博客网 时间:2024/06/05 18:04
Java学习系列(007)——继承和多态
- 继承:(inheritance):从已有的类创建新类的过程。提供继承信息的类叫父类(超类、基类),得到继承信息的类叫子类(派生类、衍生类)。
- is-a关系,子类is-a(是一个)父类
- 子类要继承父类的属性,其属性应该使用protected修饰
- 多态:(polymorphism):执行相同的行为却做了不同的事情(产生了不同的结果)。
- 方法重写(在继承过程中)
- 对象造型(将子类造型成父类)
抽象:(abstraction):寻找共性。定义类的过程就是一个抽象的过程,需要做数据抽象和行为抽象。
- 抽象类不能实例化,专门用来让别的类继承它,如果一个类中有抽象方法,那么该类必须被申明为抽象类。
相关概念
- 抽象类:被abstract关键字修饰的类,抽象类不能实例化(不能创建对象),专门为其他类提供继承信息。
- 抽象方法:如果一个方法没有方法体,就可以定义为抽象方法,也是用abstract关键字修饰,如果一个类有抽象方法,这个类必须被声明为抽象类。子类继承该抽象类时必须重写抽象方法。
- 终结类:被final关键字修饰的类,终结类不能被继承,工具类通常声明为终结类。
- 终结方法:被final关键字修饰的方法,子类中不能重写终结方法。
- 静态方法:被static修饰的方法,静态的方法和属性属于类,不属于对象,在内存中只有唯一的拷贝,静态方法和属性调用的方式是用类名调用,而不是通过对象的引用来调用。
练习:创建一个自定义窗口类、一个图形类、一个矩形类、一个椭圆类、一个直线类,编程实现在自定义窗口中画出矩形、椭圆及直线
package cn.libill.ui;import java.awt.Graphics;import javax.swing.JFrame;import cn.libill.util.MyUtil;import cn.liblill.shape.Oval;import cn.liblill.shape.Shape;/** * 自定义窗口 * @author libill * */@SuppressWarnings("serial")public class MyFrame extends JFrame { private Shape[] shapes = new Shape[100]; public MyFrame() { this.setTitle("围棋"); //设置窗口标题 this.setSize(800, 600); //设置窗口大小 this.setResizable(false); //不可调整窗口大小 this.setDefaultCloseOperation(EXIT_ON_CLOSE); //关闭窗口时退出程序(后台) this.setLocationRelativeTo(null); //窗口居中 for (int i = 0; i < shapes.length; i++) { switch(MyUtil.random(1, 3)) { case 1: shapes[i] = new Oval(); break; case 2: shapes[i] = new Oval(); break; case 3: shapes[i] = new Oval(); break; } shapes[i].setX1(MyUtil.random(0, 800)); shapes[i].setY1(MyUtil.random(0, 600)); shapes[i].setX2(MyUtil.random(0, 800)); shapes[i].setY2(MyUtil.random(0, 600)); shapes[i].setColor(MyUtil.createRandomColor()); //设置画笔颜色 } } @Override public void paint(Graphics g) { super.paint(g); /* g.setColor(Color.ORANGE); g.fillRect(0, 0, 600, 600); g.setColor(Color.BLACK); g.drawRect(36, 36, 548, 548); for (int i = 0; i < 19; i++) { g.drawLine(40, 40 + 30 * i, 580, 40 + 30 * i); g.drawLine(40 + 30 * i, 40, 40 + 30 * i, 580); } for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { g.fillOval(120 + 180 * i + 5, 120 + 180 * j + 5, 10, 10); } }*/ for (Shape s : shapes) { s.draw(g); } }}
package cn.liblill.shape;import java.awt.Color;import java.awt.Graphics;/** * 图形抽象类 * @author libill * */public abstract class Shape { protected int x1; //起点横坐标 protected int y1; //起点纵坐标 protected int x2; //终点横坐标 protected int y2; //终点纵坐标 protected Color color; //画笔颜色 /** * 绘画(抽象方法留给子类实现) * @param g 画笔 */ public abstract void draw(Graphics g); /** * 起点横坐标访问器 * @return 起点横坐标 */ public int getX1() { return x1; } /** * 起点横坐标修改器 * @param x1 起点横坐标 */ public void setX1(int x1) { this.x1 = x1; } /** * 起点纵坐标访问器 * @return 起点纵坐标 */ public int getY1() { return y1; } /** * 起点纵坐标修改器 * @param y1 起点纵坐标 */ public void setY1(int y1) { this.y1 = y1; } /** * 终点横坐标访问器 * @return 终点横坐标 */ public int getX2() { return x2; } /** * 终点横坐标修改器 * @param x2 终点横坐标 */ public void setX2(int x2) { this.x2 = x2; } /** * 终点纵坐标访问器 * @return 终点纵坐标 */ public int getY2() { return y2; } /** * 终点纵坐标修改器 * @param y2 终点纵坐标 */ public void setY2(int y2) { this.y2 = y2; } /** * 画笔颜色修改器 * @param color 画笔颜色 */ public void setColor(Color color) { this.color = color; }}
package cn.liblill.shape;import java.awt.Graphics;/** * 矩形类 * @author libill * */public class Rectangle extends Shape { @Override public void draw(Graphics g) { int x1 = getX1() < getX2() ? getX1() : getX2(); int y1 = getY1() < getY2() ? getY1() : getY2(); int x2 = getX1() > getX2() ? getX1() : getX2(); int y2 = getY1() > getY2() ? getY1() : getY2(); int width = Math.abs(x2 - x1); int height = Math.abs(y2 - y1); g.setColor(color); g.drawRect(x1, y1, width, height); }}
package cn.liblill.shape;import java.awt.Graphics;/** * 椭圆类 * @author libill * */public class Oval extends Shape { @Override public void draw(Graphics g) { int x1 = getX1() < getX2() ? getX1() : getX2(); int y1 = getY1() < getY2() ? getY1() : getY2(); int x2 = getX1() > getX2() ? getX1() : getX2(); int y2 = getY1() > getY2() ? getY1() : getY2(); int width = Math.abs(x2 - x1); int height = Math.abs(y2 - y1); g.setColor(color); g.drawOval(x1, y1, width, height); }}
package cn.liblill.shape;import java.awt.Graphics;/** * 直线类 * @author libill * */public class Line extends Shape { @Override public void draw(Graphics g) { g.setColor(color); g.drawLine(x1, y1, x2, y2); }}
package cn.libill.util;import java.awt.Color;/** * 自定义工具类 * @author libill * */public final class MyUtil { //加final表明该类不能被继承,没有任何子类(断子绝孙类) /** * 将构构器私有,不能在外部创建MyUtil类,要访问该类中的方法,只能用(MyUtil.)来调用 */ private MyUtil() { } /** * 产生指定范围的随机数 * @param min 最小值 (闭区间) * @param max 最大值 (闭区间) * @return 指定范围的随机数 */ public static int random(int min, int max) { return (int) (Math.random() * (max - min + 1) + min); } /** * 生成随机颜色 * @return Color对象 */ public static Color createRandomColor() { int r = random(0, 255); int g = random(0, 255); int b = random(0, 255); return new Color(r, g, b); }}
package cn.libill.test;import cn.libill.ui.MyFrame;/** * 测试类 * @author libill * */public class MyFrameTest { public static void main(String[] args) { new MyFrame().setVisible(true); }}
作业:公司员工有三类,分别是部门经理、程序员、销售员。部门经理每月工资8000元,程序员每小时100元,销售人员底薪1200元,加上当月销售额5%的提成,编程完成工资结算系统)
package cn.libill;/** * 员工类 * @author libill * */public abstract class Employee { protected String name; //员工姓名 /** * 构造器 * @param name 员工姓名 */ public Employee(String name) { super(); this.name = name; } /** * 工资 */ public abstract double salary(); /** * 员工姓名访问器 * @return 员工姓名 */ public String getName() { return name; }}
package cn.libill;/** * 部门经理类 * @author libill * */public class Manager extends Employee { /** * 构造器 * @param name 经理姓名 */ public Manager(String name) { super(name); } @Override public double salary() { return 8000; }}
package cn.libill;/** * 程序员类 * @author libill * */public class Programmer extends Employee { private double hours; //工作小时 /** * 构造器 * @param name 程序员姓名 */ public Programmer(String name) { super(name); } /** * 设置程序员工作多少小时 * @param hours 工作小时 */ public void setHours(double hours) { this.hours = hours; } @Override public double salary() { return 100 * hours; }}
package cn.libill;/** * 销售员类 * @author libill * */public class SalesMan extends Employee { private double salesVolume; //销售额 /** * 构造器 * @param name 销售员姓名 */ public SalesMan(String name) { super(name); } /** * 设置销售员销售额 * @param salesVolume 销售额 */ public void setSalesVolume(double salesVolume) { this.salesVolume = salesVolume; } @Override public double salary() { return 1200 + salesVolume * 0.05; }}
package cn.libill;import java.util.Scanner;/** * 工资结算类 * @author libill * */public class WageCalculation { public static void main(String[] args) { Scanner sc = new Scanner(System.in); Employee[] e = new Employee[10]; String[] names = {"张 三", "李 四", "王麻子", "王大锤", "元 芳", "刘 阳", "肖继芳", "淑 芳", "陈 明", "李 静"}; for (int i = 0; i < e.length; i++) { double m = Math.random(); if (m <= 0.6) { //60%的员工为销售员 e[i] = new SalesMan(names[i]); } else if (m <= 0.9) { //30%的员工为程序员 e[i] = new Programmer(names[i]); } else { //10%的员工为部门经理 e[i] = new Manager(names[i]); } } for (int i = 0; i < e.length; i++) { if (e[i] instanceof Manager) { System.out.printf("【%s】 职位:经 理,本月工资为:%.2f\n", e[i].getName(), e[i].salary()); } else if (e[i] instanceof Programmer) { System.out.printf("【%s】 职位:程序员, 请输入工作小时:", e[i].getName()); ((Programmer) e[i]).setHours(sc.nextDouble()); System.out.printf("\t本月工资为:%.2f\n", e[i].salary()); } else { System.out.printf("【%s】 职位:销售员, 请输入销售额:", e[i].getName()); ((SalesMan) e[i]).setSalesVolume(sc.nextDouble()); System.out.printf("\t本月工资为:%.2f\n", e[i].salary()); } } sc.close(); }}
由于部门经理、程序员和销售人员的共有特性都是公司的员工,所以创建一个Employee父类,并且都要计算工资,所以父类中应该具有姓名属性以及工资计算方法,因为在父类中无法实现对每个子类工资的计算,所以将其申明为抽象方法,让各子类去实现工资计算方法。由于父类中有抽象方法,所以父类也必须申明为抽象类。
0 0
- 【连载】Java学习系列(007)——继承和多态
- 【连载】Java学习系列(001)——Java概述和基本语法
- 【连载】Java学习系列(003)——程序逻辑-1(分支和循环)
- 【连载】Java学习系列(004)——程序逻辑-2(分支和循环)
- 【连载】Java学习系列(002)——数据类型和常用运算
- 【连载】Java学习系列(005)——数组、方法和字符串
- [连载]C#程序设计(10)--- 继承和多态
- 【连载】Java学习系列(006)——面向对象入门
- 【连载】Java学习系列(008)——深入面向对象-2
- Java学习——继承和多态
- Java学习笔记---继承和多态
- 【Java学习笔记】继承和多态
- java复习系列之封装、继承和多态
- Java学习笔记之继承和接口(二) 继承和多态、接口
- (连载)Java基础学习007
- Java学习笔记_10_继承和多态(补充)
- 机器学习从零开始系列连载(1)——基本概念
- 机器学习从零开始系列连载(2)——线性回归
- java集合框架之List
- e5-6UVA540
- 异或交换两个数
- DXP里修改丝印大小
- 杭电ACM1180——诡异的楼梯~~广度优先搜索
- 【连载】Java学习系列(007)——继承和多态
- 手机平台是指什么
- 利用Filter禁止直接访问JSP
- 循环的代价
- 线程同步四机制
- PHP 难解
- 强大全面的表单封装工具类
- Java面向第三天
- 就从今天开始吧