实验六 继承定义与使用

实验时间 2019-9-29

第一部分:理论部分。

1.继承:已有类来构建新类的一种机制。档定义了一个新类继承另一个类时,这个新类就继承了这个类的方法和域,同时在新类中添加新的方法和域以适应新的情况。

继承的特点:具有层次结构;子类继承了超类的方法和域。

2.类继承的格式:class 新类名 extends 已有类名

已有类称为:超类(superclass)、基类(base class) 或父类(parent  class)

新类称作:子类(subclass)、派生类(derived  class)或孩子类(child class)

1)继承类中,子类的构造器不能直接访问超类的私有域,必须调用超类构造器,且必须是第一条语句。

2)子类不能直接访问超类的私有域,必须和其他方法一样使用公有接口。

3)子类中可以增加域、增加方法或覆盖(override)超类的方法,但是绝不能删除超类的任何域和方法。

注:java不支持多继承。

3.多态性:泛指在程序中同一个符号在不同情况下具有不同解释。

超类方法在子类中可以重写。

java中,对象变量是多态的。

继承层次结构中,每个子类对象也可视作超类对象,因此,也可以将子类对象赋给超类变量。如:boss.setBouns(5000);

4:final类:不允许继承的类,在类的定义中用final修饰符加以说明。

5:强制转换类型:如果要把一个超类对象赋给一个子类对象变量,就必须进行强制类型转换,格式如下:Manager boss=(Manager)staff【0】;

6.抽象类:abstract class Person

1)abstract方法不能被实例化,即只能声明,不能实现!

2)包含一个或多个抽象方法的类本身必须被声明为抽象类。

7:Object类:所有类的超类。

8:equals方法:用于测试某个对象是否和另一个对象相等。如果两个对象有相同的引用,则他们一定相等。

9:hasCode方法:导出某个对象的散列码(任意整数)。

两个相等对象的散列码相等。

10:toString方法:返回一个代表该对象域值的字符串。

格式:类名【域值】

11:枚举类:它包括一个关键字enum,一个新枚举类型的名字 Grade以及为Grade定义的一组值,这里的值既非整型,亦非字符型。

1)枚举类是一个类,它的隐含超类是java.lang.Enum。

2)枚举值并不是整数或其它类型,是被声明的枚举类的自身实例

>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

继承建立了类与类的关系,同时也是多态特征的前提。

java只支持单继承,不支持多继承(避免两个父类出现同名方法的调用选择困难)

“is-a”关系是继承的一个明显特征。

2)多态:在程序中同一符号在不同情况下有不同解释。

在Java中,子类数组的引用可以转换成超类数组的引用,而不需要采用强制类型转换。

3)final类和方法:final类不允许被继承(不能做父类)

String类是一个final类的例子(故该类不能被扩展)

父类可以直接引用子类,而子类不能直接父类(必须进行强制转换类型),。咋进行强制转换类型前,先检查是否能够成功转换,使用instanceof操作符实现。

super主要有两种用法:

  • 1.super.成员变量/super.成员方法;
  • 2.super(parameter1,parameter2....)

  第一种用法主要用来在子类中调用父类的同名成员变量或者方法;第二种主要用在子类的构造器中显示地调用父类的构造器,要注意的是,如果是用在子类构造器中,则必须是子类构造器的第一个语句。

4)抽象类:一个类一定被定义成抽象类,他就是一个专职父类。不能实例化,即不能创建对象,只能产生子类。

5)受保护访问:如果希望超类的某些方法或域被子类访问,就需在给超类定义时,将这些方法或域声明为protected。

Java中用于控制可见性的4个访问修饰符:

1.仅对本类可见:private

2.对所有类可见:public

3.对本包和所有子类可见:protected

4.对本包可见:默认,不需要修饰符。

2.object类:所有类的超类。

1)equals方法:检测一个对象是否等于另外一个对象。如果两个对象具有相同的引用,那么他们一定相等。

2)equals方法具有以下特性:

自反性、对称性、传递性、一致性

3.hashCode方法(散列码):由对象导出的一个整型值。

散列码可以是任意整数。两个相等的对象要求返回相等的散列码。

4.枚举类:比较两个枚举类型值是,不用equals,直接用“==”。所有枚举类都是Enum类的子类。其中toString方法能够返回枚举常量名。

每个枚举类都有一个静态values方法,它将返回一个包含全部枚举值的数组。

 第二部分 :实验部分

1、实验目的与要求

(1) 理解继承的定义;

(2) 掌握子类的定义要求

(3) 掌握多态性的概念及用法;

(4) 掌握抽象类的定义及用途。

2、实验内容和步骤

实验1 导入第5章示例程序,测试并进行代码注释。

测试程序1:

1.在elipse IDE中编辑、调试、运行程序5-1 —5-3(教材152页-153页) ;

2. 掌握子类的定义及用法;

3. 结合程序运行结果,理解并总结OO风格程序构造特点,理解Employee和Manager类的关系子类的用途,并在代码中添加注释;

实验5-1代码如下:

ManagerTest:

package inheritance;

/**
* This program demonstrates inheritance.
* @version 1.21 2004-02-21
* @author Cay Horstmann
*/
public class ManagerTest
{
public static void main(String[] args)
{ var boss = new Manager("Carl Cracker", 80000, 1987, 12, 15);//构建管理者对象
boss.setBonus(5000); var staff = new Employee[3]; //用管理者和雇员对象填充工作人员数组 staff[0] = boss;
staff[1] = new Employee("Harry Hacker", 50000, 1989, 10, 1);
staff[2] = new Employee("Tommy Tester", 40000, 1990, 3, 15); //遍历打印所有员工对象的信息
for (Employee e : staff)
System.out.println("name=" + e.getName() + ",salary=" + e.getSalary());
}
}
Manager类:
//package inheritance;

public class Manager extends Employee//继承于Employee的子类
{
private double bonus; /**
* @param name the employee's name
* @param salary the salary
* @param year the hire year
* @param month the hire month
* @param day the hire day
*/
public Manager(String name, double salary, int year, int month, int day)//Manager构造器
{
super(name, salary, year, month, day);//调用父类构造器
bonus = 0;
} public double getSalary()//对于Salary的get方法
{
double baseSalary = super.getSalary();//基本工资由父类getSalary获得
return baseSalary + bonus;
} public void setBonus(double b)
{
bonus = b;
}
}
Employee类:
//package inheritance;

import java.time.*;

public class Employee
{
private String name;
private double salary;
private LocalDate hireDay; public Employee(String name, double salary, int year, int month, int day)
{
this.name = name;
this.salary = salary;
hireDay = LocalDate.of(year, month, day);
} public String getName()
{
return name;
} public double getSalary()
{
return salary;
} public LocalDate getHireDay()
{
return hireDay;
} public void raiseSalary(double byPercent)
{
double raise = salary * byPercent / 100;
salary += raise;
}
}

运行结果如下:

测试程序2:

1. 编辑、编译、调试运行教材PersonTest程序(教材163页-165页);

2.掌握超类的定义及其使用要求;

3. 掌握利用超类扩展子类的要求;

4.在程序中相关代码处添加新知识的注释;

5. 删除程序中Person类、PersonTest类,背录删除类的程序代码,在代码录入中理解抽象类与子类的关系和使用特点。

实验5-2代码如下:

PersonTest:
//package abstractClasses;

/**
* This program demonstrates abstract classes.
* @version 1.01 2004-02-21
* @author Cay Horstmann
*/
public class PersonTest
{
public static void main(String[] args)
{
var people = new Person[2]; //用Student和Employee对象填充人员数组
people[0] = new Employee("Harry Hacker", 50000, 1989, 10, 1);
people[1] = new Student("Maria Morris", "computer science"); // 打印所有Person对象的名称和描述
for (Person p : people)
System.out.println(p.getName() + ", " + p.getDescription());
}
}

person类:

//package abstractClasses;

public abstract class Person//定义抽象类型Person
{
public abstract String getDescription();//定义抽象描述
private String name; public Person(String name)
{
this.name = name;
} public String getName()
{
return name;
}
}

Employee类:

//package abstractClasses;

import java.time.*;

public class Employee extends Person//子类Employee继承父类Person
{
private double salary;
private LocalDate hireDay; public Employee(String name, double salary, int year, int month, int day)
{
super(name);//继承父类的方法
this.salary = salary;
hireDay = LocalDate.of(year, month, day);//hireDay使用LocalDate的方法
} public double getSalary()
{
return salary;
} public LocalDate getHireDay()
{
return hireDay;
} public String getDescription()
{
return String.format("an employee with a salary of $%.2f", salary);
} public void raiseSalary(double byPercent)
{
double raise = salary * byPercent / 100;
salary += raise;
}
}

Student类:

//package abstractClasses;

public class Student extends Person//子类Student继承父类Person
{
private String major; /**
* @param name the student's name
* @param major the student's major
*/
public Student(String name, String major)
{
// pass name to superclass constructor
super(name);// 将name传递给父类构造函数
this.major = major;
} public String getDescription()
{
return "a student majoring in " + major;
}
}

运行结果如下:

删除后override的代码如下:

//package abstractClasses;

import java.time.*;

public class Employee extends Person
{
public Employee(String name, int i, int j, int k, int l) {
super(name);
// TODO Auto-generated constructor stub
}
@Override
public String getDescription() {
// TODO Auto-generated method stub
return null;
}
@Override
public String getName() {
// TODO Auto-generated method stub
return super.getName();
}
private double salary;
private LocalDate hireDay; /*public Employee(String name, double salary, int year, int month, int day)
{
super(name);
this.salary = salary;
hireDay = LocalDate.of(year, month, day);
} public double getSalary()
{
return salary;
} public LocalDate getHireDay()
{
return hireDay;
} public String getDescription()
{
return String.format("an employee with a salary of $%.2f", salary);
} public void raiseSalary(double byPercent)
{
double raise = salary * byPercent / 100;
salary += raise;
}*/
}
  • 抽象类与子类的关系及使用特点:

  a)abstract方法只能声明,不能实现

  b)包含一个或多个抽象方法的类本身必须被声明为抽象类

  c)抽象方法充当着占位的角色,它们的具体实现在子类中

  d)抽象类不能被实例化,即不能创建对象,只能产生子类。

测试程序3:

1.编辑、编译、调试运行教材程序5-8、5-9、5-10,结合程序运行结果理解程序(教材174页-177页);

2.掌握Object类的定义及用法;

3.在程序中相关代码处添加新知识的注释。

5-8示例程序:

Employee:
//package equals;

import java.time.*;
import java.util.Objects; public class Employee
{
private String name;
private double salary;
private LocalDate hireDay; public Employee(String name, double salary, int year, int month, int day)
{
this.name = name;
this.salary = salary;
hireDay = LocalDate.of(year, month, day);
} public String getName()
{
return name;
} public double getSalary()
{
return salary;
} public LocalDate getHireDay()
{
return hireDay;
} public void raiseSalary(double byPercent)
{
double raise = salary * byPercent / 100;
salary += raise;
} public boolean equals(Object otherObject) //Objects类中的equals方法用于检测一个对象是否等于另外一个对象
{
// a quick test to see if the objects are identical
if (this == otherObject) return true; // must return false if the explicit parameter is null
if (otherObject == null) return false; //如果显示参数为空,则返回false // if the classes don't match, they can't be equal
if (getClass() != otherObject.getClass()) return false; //如果不是相同类型的对象,则返回false,getClass方法将返回一个对象所属的类 // now we know otherObject is a non-null Employee
var other = (Employee) otherObject; // test whether the fields have identical values
return Objects.equals(name, other.name)
&& salary == other.salary && Objects.equals(hireDay, other.hireDay);
} public int hashCode()
{
return Objects.hash(name, salary, hireDay);
/*Objects.hash() 这个类用于操作对象的静态实用方法这些工具包括用于计算对象的哈希代码的空安全或空容错方法,返回一个对象的字符串,并比较两个对象
Object类中的hashCode方法导出某个对象的散列码。散列码世人以整数,表示对象的存储地址
两个相等对象的散列码相等*/
} public String toString() //方法返回一个代表该对象域值的字符串
//toString
{
return getClass().getName() + "[name=" + name + ",salary=" + salary + ",hireDay="
+ hireDay + "]";
}
}

Manager:

package equals;

public class Manager extends Employee//子类Manager继承父类Employee
{
private double bonus; public Manager(String name, double salary, int year, int month, int day)
{
super(name, salary, year, month, day);
bonus = 0;
} public double getSalary()
{
double baseSalary = super.getSalary();
return baseSalary + bonus;
} public void setBonus(double bonus)
{
this.bonus = bonus;
} public boolean equals(Object otherObject)
{
if (!super.equals(otherObject)) return false;
Manager other = (Manager) otherObject;
// super.equals检查这个和其他属于同一个类
return bonus == other.bonus;
} public int hashCode()
{
return java.util.Objects.hash(super.hashCode(), bonus);
} public String toString()
{
return super.toString() + "[bonus=" + bonus + "]";
}
}
 EqualsTest:
package equals;

/**
* This program demonstrates the equals method.
* @version 1.12 2012-01-26
* @author Cay Horstmann
*/
public class EqualsTest
{
public static void main(String[] args)
{
Employee alice1 = new Employee("Alice Adams", 75000, 1987, 12, 15);
Employee alice2 = alice1;
Employee alice3 = new Employee("Alice Adams", 75000, 1987, 12, 15);
Employee bob = new Employee("Bob Brandson", 50000, 1989, 10, 1); System.out.println("alice1 == alice2: " + (alice1 == alice2)); System.out.println("alice1 == alice3: " + (alice1 == alice3)); System.out.println("alice1.equals(alice3): " + alice1.equals(alice3)); System.out.println("alice1.equals(bob): " + alice1.equals(bob)); System.out.println("bob.toString(): " + bob); Manager carl = new Manager("Carl Cracker", 80000, 1987, 12, 15);
Manager boss = new Manager("Carl Cracker", 80000, 1987, 12, 15);
boss.setBonus(5000);
System.out.println("boss.toString(): " + boss);
System.out.println("carl.equals(boss): " + carl.equals(boss));
System.out.println("alice1.hashCode(): " + alice1.hashCode());
System.out.println("alice3.hashCode(): " + alice3.hashCode());
System.out.println("bob.hashCode(): " + bob.hashCode());
System.out.println("carl.hashCode(): " + carl.hashCode());
}
}

运行结果如下:

实验2:编程练习

1.定义抽象类Shape:

2.属性:不可变常量double PI,值为3.14;

3.方法:public double getPerimeter();public double getArea())。

  让Rectangle与Circle继承自Shape类。

   编写double sumAllArea方法输出形状数组中的面积和和double sumAllPerimeter方法输出形状数组中的周长和。

   main方法中

1)输入整型值n,然后建立n个不同的形状。如果输入rect,则再输入长和宽。如果输入cir,则再输入半径。
2) 然后输出所有的形状的周长之和,面积之和。并将所有的形状信息以样例的格式输出。
3) 最后输出每个形状的类型与父类型,使用类似shape.getClass()(获得类型),shape.getClass().getSuperclass()(获得父类型);

思考sumAllArea和sumAllPerimeter方法放在哪个类中更合适?

输入样例:

3

rect

1 1

rect

2 2

cir

1

输出样例:

18.28

8.14

[Rectangle [width=1, length=1], Rectangle [width=2, length=2], Circle [radius=1]]

class Rectangle,class Shape

class Rectangle,class Shape

class Circle,class Shape

编程练习代码如下:

  • shape:
package shape;

import java.util.Scanner;
public class Test {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
System.out.println("个数");
int a = in.nextInt();
System.out.println("种类");
String rect="rect";
String cir="cir";
Shape[] num=new Shape[a];
for(int i=0;i<a;i++){
String input=in.next();
if(input.equals(rect)) {
System.out.println("长和宽");
int length = in.nextInt();
int width = in.nextInt();
num[i]=new Rectangle(width,length);
System.out.println("Rectangle["+"length:"+length+" width:"+width+"]");
}
if(input.equals(cir)) {
System.out.println("半径");
int radius = in.nextInt();
num[i]=new Circle(radius);
System.out.println("Circle["+"radius:"+radius+"]");
}
}
Test c=new Test();
System.out.println("求和");
System.out.println(c.sumAllPerimeter(num));
System.out.println(c.sumAllArea(num)); for(Shape s:num) {
System.out.println(s.getClass()+","+s.getClass().getSuperclass());
}
} public double sumAllArea(Shape score[])
{
double sum=0;
for(int i=0;i<score.length;i++)
sum+= score[i].getArea();
return sum;
}
public double sumAllPerimeter(Shape score[])
{
double sum=0;
for(int i=0;i<score.length;i++)
sum+= score[i].getPerimeter();
return sum;
}
}

demo:

package shape;

abstract class Shape { //定义抽象父类Shape
abstract double getPerimeter(); //定义求解周长的方法
abstract double getArea(); //定义求解面积的方法
} class Rectangle extends Shape{
private int length;
private int width;
public Rectangle(int length, int width) {
this.length = length;
this.width = width;
}
//继承父类
double getPerimeter(){ //调用父类求周长的方法
return 2*(length+width);
}
double getArea(){
return length*width; //调用父类求面积的方法
}
} class Circle extends Shape{
private int radius;
public Circle(int radius) {
this.radius = radius;
}
double getPerimeter(){
return 2 * Math.PI * radius;
}
double getArea(){
return Math.PI * radius * radius;
}
}

运行结果如下:

小结:

    通过本周的学习,我了解到了什么是继承(新类继承了旧类的方法和域,并添加了新的方法和域)以及它的特点和优点,并通过老师的讲解和课后的学习,大致明白了什么是类、子类、超类,掌握了父类与子类的部分用法,学会了如何定义抽象类,使用super关键字等。初步的理解了继承的结构层次和多态性的概念。在课下的学习中,通过示例程序以及查阅资料,也学到了很多有用的知识。

201871010109-胡欢欢《面向对象程序设计(java)》第6-7周学习总结的更多相关文章

  1. 201571030332 扎西平措 《面向对象程序设计Java》第八周学习总结

    <面向对象程序设计Java>第八周学习总结   项目 内容 这个作业属于哪个课程 https://www.cnblogs.com/nwnu-daizh/ 这个作业的要求在哪里 https: ...

  2. 201771010118马昕璐《面向对象程序设计java》第八周学习总结

    第一部分:理论知识学习部分 1.接口 在Java程序设计语言中,接口不是类,而是对类的一组需求描述,由常量和一组抽象方法组成.Java为了克服单继承的缺点,Java使用了接口,一个类可以实现一个或多个 ...

  3. 201771010134杨其菊《面向对象程序设计java》第十周学习总结

    第8章泛型程序设计学习总结 第一部分:理论知识 主要内容:   什么是泛型程序设计                   泛型类的声明及实例化的方法               泛型方法的定义      ...

  4. 201771010134杨其菊《面向对象程序设计java》第八周学习总结

    第八周学习总结 第一部分:理论知识 一.接口.lambda和内部类:  Comparator与comparable接口: 1.comparable接口的方法是compareTo,只有一个参数:comp ...

  5. 201771010134杨其菊《面向对象程序设计java》第七周学习总结

    第七周学习总结 第一部分:理论知识 1.继承是面向对象程序设计(Object Oriented Programming-OOP)中软件重用的关键技术.继承机制使用已经定义的类作为基础建立新的类定义,新 ...

  6. 201771010118 马昕璐《面向对象程序设计java》第十周学习总结

    第一部分:理论知识学习部分 泛型:也称参数化类型(parameterized type)就是在定义类.接口和方法时,通过类型参数 指示将要处理的对象类型. 泛型程序设计(Generic program ...

  7. 201871010126 王亚涛《面向对象程序设计 JAVA》 第十三周学习总结

      内容 这个作业属于哪个课程 https://www.cnblogs.com/nwnu-daizh/ 这个作业的要求在哪里 https://www.cnblogs.com/nwnu-daizh/p/ ...

  8. 马凯军201771010116《面向对象程序设计Java》第八周学习总结

    一,理论知识学习部分 6.1.1 接口概念 两种含义:一,Java接口,Java语言中存在的结构,有特定的语法和结构:二,一个类所具有的方法的特征集合,是一种逻辑上的抽象.前者叫做“Java接口”,后 ...

  9. 周强201771010141《面向对象程序设计Java》第八周学习总结

    一.理论知识学习部分 Java为了克服单继承的缺点,Java使用了接口,一个类可以实现一个或多个接口. 接口体中包含常量定义和方法定义,接口中只进行方法的声明,不提供方法的实现. 类似建立类的继承关系 ...

  10. 201777010217-金云馨《面向对象程序设计Java》第八周学习总结

    项目 内容 这个作业属于哪个课程 https://www.cnblogs.com/nwnu-daizh/ 这个作业的要求在哪里 https://www.cnblogs.com/nwnu-daizh/p ...

随机推荐

  1. 【简单的spfa+优先队列】

    题目是给出只有x和y构成的图,相同元素走路不花费,不同元素间花费1,给出起点终点,最少花费是 #include<cstdio>#include<algorithm>#inclu ...

  2. MySQL学习笔记8——多表查询

    多表查询 多表查询 *合并结果集 *连接查询 *子查询 合并结果集 *要求被合并的表中,列的类型和列数相同(实际上是查询的结果集列类型和列数相同即可) *UNION,去除重复行 *UNION ALL, ...

  3. CF1225B1 TV Subscriptions (Easy Version)

    CF1225B1 TV Subscriptions (Easy Version) 洛谷评测传送门 题目描述 The only difference between easy and hard vers ...

  4. Django middleware (中间件)

    关于中间价: django 中的中间件其实就是一个类,在请求到来和结束后,django会根据自己的规则在合适的时机执行中间件中相应的方法. 在django项目的settings中,有一个 MIDDLE ...

  5. Paper | Multi-scale Dense Networks for Resource Efficient Image Classification

    目录 故事背景 方法 两种加速策略 网络设计 网络优化 失败设计 回头品味 实验 数据集和数据处理 结果 第二次阅读 本文不是第一个提出early exit思想的 写作流畅 网络回顾 其他 发表在IC ...

  6. oracle导入Excel表文本数据

    首先导Excel表数据要先建和Excel表字段对应的表,然后将Excel表另存为Txt文本, 然后在Plsql客户端点击工具->文本导入器 然后这里要选择用户及其表,点击导入数据就可以

  7. Python复杂对象转JSON

    Python复杂对象转JSON在Python对于简单的对象转json还是比较简单的,如下: import json d = {'a': 'aaa', 'b': ['b1', 'b2', 'b3'], ...

  8. RocketMQ多master多salve集群搭建

    一.RocketMQ集群模式简介 单Master方式 风险比较大, 一旦Broker重启或者宕机, 将导致整个环境不可用, 不建议线上使用. 多Master模式 一个集群中没有slave, 全是mas ...

  9. C#获取文件夹下所有的文件名称

    例如想获取后缀名为.txt的文件 //第一种方法 var files = Directory.GetFiles(path, "*.txt"); foreach (var file ...

  10. Web Api全局预防Xss攻击

    本文转载自https://www.cnblogs.com/ruanyifeng/p/4739807.html.对第二种过滤方法的代码进行了一些修改和注释,记录一下免得以后忘了.已经测试过,应该可以直接 ...