学堂在线—Java程序设计—课程笔记(第3章 类的重用)

第3章 类的重用

3.1 类继承的概念和语法、隐藏和覆盖

  1. Java只支持类的单继承,每个子类只能有一个直接超类;
    超类是所有子类的公共属性及方法的几何,子类是超类的特殊化;
    子类对象从外部来看:与超类相同的接口,可以有更多方法和数据成员;
    子类内包含着超类的所有变量和方法;
  2. 子类不能直接访问从超类中继承的私有属性及方法,可使用公有(及保护)方法进行访问;
  3. 属性的隐藏:
    子类中声明了与超类相同的成员变量名;
    子类拥有了两个相同名字的变量;
    子类执行继承自超类的操作时,处理超类变量;
    子类执行自己声明的方法时,处理自己的变量;
    super.属性名:直接访问超类属性;
    静态成员:仍只有一个;
  4. 方法的覆盖:
    子类不需从超类继承来的方法和功能,可以声明同名方法;
    覆盖方法的返回类型、方法名称、参数个数和类型必须一致,访问权限不能更严格;
    抽象方法必须覆盖,否则子类也成为了抽象类;
    不能覆盖final方法、静态方法;
    super.方法名:直接调用被覆盖的方法;

3.2 Object类

  1. Object类:所有类的直接或间接超类,类层次最高点;包含了所有Java类公共属性;
  2. Object类主要方法:getClass()、toString()、equals(Object obj)、clone()、hashCode()、finaliza();
  3. equals方法:
    相等:两个对象类型相同、属性值相同;
    同一:两个引用变量指向同一个对象;
    同一肯定相等,相等不一定同一;
    == 、equals判断的是两个引用是否同一;
  4. hashCode方法:返回对象散列码;
    在一个Java程序的一次执行过程中,如果对象“相等比较”所使用的信息没有被修改,同一对象执行hashCode方法每次都返回同一个整数,不同执行中返回值不必一致;
    如果依靠equals方法两个对象是相等的,则应返回同样的整数结果;
    如果依靠equals方法两个对象不相等,不要求返回值不同;
  5. clone方法:复制对象;
    clone在Object中被定义为protected,覆盖为public;
    实现Cloneable接口,赋予一个对象被克隆的能力(cloneability);
  6. finalize方法:对象被垃圾回收器回收前系统自动调用;
    覆盖finalize方法的最后必须调用super.finalize;
  7. getClass方法:final方法,返回一个Class对象;
    通过Class对象,可以查询类的各种信息:名字、超类、实现接口的名字等;
  8. notify、notifyAll、wait方法:final方法,主要用在多线程程序中;

3.3 终结类与终结方法、抽象类

  1. 终结类与终结方法:final修饰的类和方法;
    终结类不能被继承;
    终结方法不能被子类覆盖;
  2. 抽象类前加abstract,可包含常规类任何成员,包括非抽象方法和抽象方法;
    抽象方法:用abstract修饰,只有方法原型,没有方法实现;
    抽象类没有具体实例,只能用作超类;
    子类实现所有抽象方法后,才不是抽象类能产生实例,有抽象方法时仍为抽象类;

3.4 泛型、类的组合

  1. 泛型Type:类型可定制(类、方法、接口);
    通配符?
    有限制的泛型:在参数Type后面使用extends关键字并加上类名或接口名,表示参数所代表的类型必须是该类的子类或者实现了该接口(此处接口用extends而非implements);
  2. 组合的语法:将已存在类的对象放到新类中;
    继承——从属;
    组合——包含;

编程练习题

1. 教师学生评分

题目

学校要进行年终总结,需要对教师和学生的评分结果进行统计。学生的统计数据有三个,教师的统计数据有四个。请你实现一个统计系统,对输入的数据进行整理。
请你实现一个Person类表示人员,并实现一些必要的方法,再实现Teacher类和Student类,通过类的继承机制完成这个任务。
输入格式:
首先输入一个数字N,表示输入统计的人数。
接下来是N行,每行是用空格隔开的一系列数字。
输出格式:
N行,每行是一个标识符加一个平均得分(向下取整的整数),用空格隔开。
学生的标识符是Student,教师的标识符是Teacher。
输入样例:
2
2 3 4
2 3 4 5
输出样例:
Student 3
Teacher 3

思路

类的设计按题目要求即可。
使用方法:str.split(“ ”) 切分字符串,Interger.valueOf(str) 将字符串转换为整形。

代码

import java.util.Scanner;

class Person {
	private int[] score;
	private int len;
	
	Person(int score[], int len) {
		this.len = len;
		this.score = new int[len];
		for (int i = 0; i < len; i++) {
			this.score[i] = score[i];
		}
	}
	
	protected int Ave() {
		int sum = 0;
		for (int i = 0; i < len; i++)
			sum += score[i];
		return sum/len;
	}	
}

class Student extends Person {
	Student(int[] score) {
		super(score, 3);
	}
}

class Teacher extends Person {
	Teacher(int[] score) {
		super(score, 4);
	}
}

public class homework3_1 {
	public static void main(String[] args) {
		Scanner in = new Scanner(System.in);
		int n = in.nextInt();
		int ans[] = new int[n];
		String per[] = new String[n];
		in.nextLine();
		for (int i = 0; i < n; i++) {
			String input = in.nextLine();
			String[] inum = input.split(" ");
			int len = inum.length;
			int[] num = new int[len];
			for (int j = 0; j < len; j++)
				num[j] = Integer.valueOf(inum[j]);
			if (len == 3) {
				Student stu = new Student(num);
				ans[i] = stu.Ave();
				per[i] = "Student";
			}
			else {
				Teacher tea = new Teacher(num);
				ans[i] = tea.Ave();
				per[i] = "Teacher";
			}
		}
		in.close();
		for (int i = 0; i < n; i++)
			System.out.println(per[i] + " " + ans[i]);
	}
}

2. 图形面积计算

题目

我们有一些图形的边长数据,这些图形包括三角形和矩形,请你编写一个程序求出它们的面积。
请你实现一个基础图形类Graph,然后实现三角形类Triangle和矩形类Rectangle,继承自Graph。根据输入的边数实现不同的对象,并计算面积。
输入格式:
一行,一个整数n,表示图形个数。
n行,每行是用空格隔开的整数。
输出格式:
n行,每行是一个图形的面积。
输入样例:
2
5 5
6 6 6
输出样例:
25
15

思路

与上题类似,参考编程题 2-3 的三角形面积公式。

代码

import java.util.Scanner;

abstract class Graph {
	protected int[] side;
	protected int num;
	Graph(int side[], int num) {
		this.num = num;
		this.side = new int[num];
		for (int i = 0; i < num; i++)
			this.side[i] = side[i];
	}
	abstract int getArea();
}

class Rectangl extends Graph {
	Rectangl(int[] side) {
		super(side, 2);
	}
	
	int getArea() {
		return side[0] * side[1];
	}
}

class Triangle extends Graph {
	public Triangle(int[] side) {
		super(side, 3);
	}
	
	int getArea() {
		double p = (double)(side[0] + side[1] + side[2]) / 2;
		return (int)Math.sqrt(p * (p - side[0]) * (p - side[1]) * (p - side[2]));
	}
}

public class homework3_2 {
	public static void main(String[] args) {
		Scanner in = new Scanner(System.in);
		int n = in.nextInt();
		int ans[] = new int[n];		
		in.nextLine();
		
		for (int i = 0; i < n; i++) {
			String input = in.nextLine();
			String[] iside = input.split(" ");
			int num = iside.length;
			int[] side = new int[num];
			for (int j = 0; j < num; j++)
				side[j] = Integer.valueOf(iside[j]);
			if (num == 2) {
				Rectangl rec = new Rectangl(side);
				ans[i] = rec.getArea();
			}
			else {
				Triangle tri = new Triangle(side);
				ans[i] = tri.getArea();
			}
		}
		in.close();
		for (int i = 0; i < n; i++)
			System.out.println(ans[i]);
	}
}

3.多类型排序

题目

我们现在有一些数据,是整数和字符串混杂的。现在需要你将他们分开,并且分别进行排序。
请你利用泛型实现一个数组类,并且实现排序函数,使得其既可以对Integer类型进行排序,又可以对String类型进行排序。然后利用你实现的这个类完成上面的任务。
输入格式:
一行,一个数字n,表示元素的个数。
n行,每行一个字符串整数,也可以是其他字符串。
输出格式:
n行,前面一部分为输入的整数字符串按从小到大排序输出,后面一部分为非整数字符串按照字典序从小到大输出。
输入样例:
5
12
ab
bd
23
t
输出样例:
12
23
ab
bd
t

思路

  1. 设计类时,通过实现Comparable接口,支持排序(无复杂度要求,用冒泡排序即可)。
  2. 实现Comparable接口的泛型变量数组创建方式:
    this.object = (T[]) new Comparable[length];
    因为必须是Comparable的子类,不能通过new Object创建(Object不是Comparable子类)。
  3. 通过字符串对应字符的ASCII码区分是数字还是其他字符串:
    input.charAt(0) > 47 && input.charAt(0) < 58

代码

import java.util.Scanner;

class mArray<T extends Comparable<T>> { // Comparable:实现Comparable接口->支持排序
	int length;
	T[] object;

	mArray(T[] object, int length) {
		this.length = length;
//		this.object = (T[]) new Object[length]; //Object不是Comparable子类
		this.object = (T[]) new Comparable[length];
		for (int i = 0; i < length; i++)
			this.object[i] = object[i];
	}

	void mSort() {
		for (int i = 0; i < length; i++) {
			for (int j = i + 1; j < length; j++) {
				int key = object[i].compareTo(object[j]);
				if (key > 0) {
					T tmp = object[i];
					object[i] = object[j];
					object[j] = tmp;
				}
			}
		}
		for (int i = 0; i < length; i++)
			System.out.println(object[i]);
	}
}

public class homework3_3 {
	public static void main(String[] args) {
		Scanner in = new Scanner(System.in);
		int n = in.nextInt();
		in.nextLine();
		int strnum = 0, intnum = 0;
		String[] str = new String[n];
		Integer[] num = new Integer[n];

		for (int i = 0; i < n; i++) {
			String input = in.nextLine();
			if (input.charAt(0) > 47 && input.charAt(0) < 58) 
				num[intnum++] = Integer.valueOf(input);
			else 
				str[strnum++] = input;
		}
		in.close();
		
		mArray<Integer> iArray = new mArray<Integer>(num, intnum);
		iArray.mSort();
		mArray<String> sArray = new mArray<String>(str, strnum);
		sArray.mSort();

	}

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值