首页 > 技术文章 > Educoder-Java程序开发基础-类和对象(二)

junun 2021-07-15 17:03 原文

第1关:类和对象:封装和信息隐藏

​ 本关任务:如何实现同类不同个体共性的抽象;如何实现数据和方法的封装(类);如何通过一个模板(类)来创建活生生的个体(对象);如何访问对象的成员(数据成员和方法成员)

class Person {
	//定义两个属性name和age
	String name ; int age;
	public Person(String name,int age){
		this.name=name ; this.age=age;
	}
	//定义方法show(),显示人的姓名和年龄信息
	public void show(){
		System.out.println("姓名:"+name+" 年龄:"+age);
	}
	
}
public class PersonTest {
	public static void main(String[] args) {
		//创建一个Person类对象p
		Person p = new Person("张三",18);
		//设置对象p的姓名为"张三",年龄为18
		p.show();
		//显示对象p的信息
    }
}

第2关:类成员的访问控制:不要随便碰我!

​ 本关任务:如何实现信息隐藏;如何实现类成员的访问控制(private,缺省,public)、如何间接访问类的私有成员

//1.在构造方法中区分成员变量和形参变量;
//2.当类重载多个构造方法时,如果在构造内部调用另一个构造时,不能直接写构造名,要写this(;
//注意this关键字的使用,请同学们总结this关键字的三个用途
class Person {
	//定义两个数据成员name和age,并声明为私有的
    private String name;
    private int age;
	/*定义四个public方法getName(),setName(),getAge()和setAge()
	设置或获取两个数据成员name和age的值
	*/
	public void setName(String name) {
		this.name=name;
	}
	//设置年龄
	public void setAge(int age) {
		this.age=age;
	}
	//获取姓名
	public String getName() {
		//获取姓名属性值
		return name;
	}
	//获取年龄
	public int getAge() {
		//获取年龄属性值
		return this.age;
	}	
	//定义方法show()显示姓名和年龄信息
	public void show(){
        System.out.println("姓名:"+name+" 年龄:"+age);
    }
}
public class PersonTest {
	public static void main(String[] args) {
		//创建一个Person类对象p
		Person p = new Person();
		//设置对象p的姓名为"张三",年龄为18
		p.setName("张三"); p.setAge(18);		//name和age是私有的所以需要用到同类下的set
		//显示相关信息
		p.show();	
	}
}

第3关:this关键字:我是谁?

​ 本关任务:通过实践了解this关键字的使用

//1.在构造方法中区分成员变量和形参变量;
//2.当类重载多个构造方法时,如果在构造内部调用另一个构造时,不能直接写构造名,要写this(;
//注意this关键字的使用,请同学们总结this关键字的三个用途
//注意this关键字的使用,请同学们总结this关键字的三个用途
class Person{
	private String name;
	private int age;
	//一个参数的构造函数
	public Person(String name) {
		this.name = name;
	}
	//两个参数的构造函数
	public Person(String name,int age) {
		//通过this调用一个参数的构造函数
		this.name=name;
		this.age = age;
	}
	//设置姓名
	public void setName(String name) {
		this.name=name;
	}
	//设置年龄
	public void setAge(int age) {
		this.age=age;
	}
	//获取姓名
	public String getName() {
		//获取姓名属性值
		return name;
	}
	//获取年龄
	public int getAge() {
		//获取年龄属性值
		return age;
	}	
	//对象引用自我克隆
	public Person selfClone() {
		//返回当前对象引用
		return this;
	}
}
public class PersonTest {
	public static void main(String[] args) {
		//创建一个对象p1,设置姓名为张三,年龄为18 同学们可以尝试多种方法
		Person p = new Person("张三",18);
		//通过对象引用克隆创建对象引用p2
		Person p2 = p.selfClone();
		//显示对象p2的姓名、年龄信息,补充完下列两行代码。
		System.out.println("姓名:"+p2.getName());
		System.out.println("年龄:"+p2.getAge());
	}
}

第4关:构造函数及构造函数重载

​ 本关任务:了解构造方法的定义方法,了解构造方法的重载方法,掌握创建对象时如何实现对象数据成员的不同初始化方法

import java.util.Scanner;	//扫描器类
class Person{
	private String name;
	private int age;
	//定义无参构造函数,设置为缺省值张三,年龄为18
	public Person(){
		this.name="张三";
		this.age=18;
	}
	//定义有一个参数的构造函数,根据参数设置姓名,设置年龄为缺省值18
	public Person(String name){
		this.name=name;
		this.age=18;
	}
	//定义两个参数的构造函数,根据两个参数设置姓名、年龄
	public Person(String name,int age){
		this.name=name;
		this.age=age;
	}
	//设置姓名
	public void setName(String name) {
		this.name = name;
	}
	//获取姓名
	public String getName() {
		return this.name;
	}
	//设置年龄
	public void setAge(int age) {
		this.age = age;
	}
	//获取年龄
	public int getAge() {
		return this.age;
	}
	//显示姓名、年龄等信息
	public void show() {
		System.out.println("姓名:"+this.name+" 年龄"+this.age);
	}
}
public class PersonTest {
	public static void main(String[] args) {
		String name; int age;
		//创建一个对象p1,设置姓名为缺省值张三,年龄为缺省18
		Person p1 = new Person("张三",18);
		//输入姓名
		Scanner input = new Scanner(System.in);		//创建扫描器
		name = input.next();	//通过键盘输入姓名
		//创建一个对象p2,设置姓名为输入值,年龄为缺省值18
		Person p2 = new Person(name);
		//输入姓名和年龄
		name = input.next();
		age = input.nextInt();
		//创建一个对象p3,设置姓名、年龄为输入值
		Person p3 = new Person(name,age);
		//显示对象p1,p2,p3的姓名、年龄信息。
		p1.show();
		p2.show();
		p3.show();
	}
}

第5关:类成员方法重载

​ 本关任务:通过实现Student类中的setCard()方法的重载,掌握为什么要求引入方法重载,如何实现方法重载

class Student{
	private String name;
	private int score; //成绩
	private String level; //等级
	//setCard()重载方法1 设置学生成绩
	public void setCard(int score) {
		System.out.println("重载方法1,成绩="+score);
	}
	//setCard()重载方法2 设置学生等级 
	public void setCard(String level){
		System.out.println("重载方法2,等级="+level);
	}
	//setCard()重载方法3 设置学生成绩和登记
	public void setCard(int score,String level){
		System.out.println("重载方法3,成绩="+score+",等级="+level);
	}
}
public class StudentTest {
	public static void main(String[] args) {
		// 创建一个学生对象s
		Student s = new Student();
		//设置学生成绩为90
		s.setCard(90);
		//设置学生等级为良好
		s.setCard("良好");
		//设置学生成绩为75,等级为中等
		s.setCard(75, "中等");
    }
}

第6关:构造代码块

​ 本关任务:了解构造代码块的作用:确保用不同途径创建同类对象时都能做一些共性的初始化工作

/*执行顺序:(优先级从高到低。)静态代码块>mian方法>构造代码块>构造方法。
其中静态代码块只执行一次。构造代码块在每次创建对象是都会执行。
*/
import java.util.Scanner;
class Person{
	private String name;
	private int age;
	//根据输出要求写出构造代码块
{
	System.out.println("调用构造代码块,准备创建一个人类对象");
}
	//定义无参构造函数,设置为缺省值张三,年龄为18
	public Person(){
		this.name="张三";
		this.age=18;
		System.out.println("调用无参构造方法");
	}
	//定义有一个参数的构造函数,根据参数设置姓名,设置年龄为缺省值18
	public Person(String name){
		this.name=name;
		this.age=18;
		System.out.println("调用一个参数的构造方法");
	}	
	//定义两个参数的构造函数,根据两个参数设置姓名、年龄
	public Person(String name,int age){
		this.name=name;
		this.age=age;
		System.out.println("调用两个参数的构造方法");
	}		
	//设置姓名
	public void setName(String name) {
		this.name = name;
	}
	//获取姓名
	public String getName() {
		return this.name;
	}
	//设置年龄
	public void setAge(int age) {
		this.age = age;
	}
	//获取年龄
	public int getAge() {
		return this.age;
	}
	//显示姓名、年龄等信息
	public void show() {
		System.out.println("姓名:"+this.name+" 年龄:"+this.age);
	}
}
public class PersonTest {

	public static void main(String[] args) {
		String name;
		int age;
		//创建一个对象p1,设置姓名为缺省值张三,年龄为缺省18
		Person p1 = new Person();
		//显示对象p1的姓名、年龄信息。
		p1.show();
		//输入姓名
		Scanner input = new Scanner(System.in);
		name = input.next();
		//创建一个对象p2,设置姓名为输入值,年龄为缺省值18
		Person p2 = new Person(name);
		//显示对象p2的姓名、年龄信息。
		p2.show();
		//输入姓名和年龄
		name = input.next();
		age = input.nextInt();
		//创建一个对象p3,设置姓名、年龄为输入值
		Person p3 = new Person(name,age);
		//显示对象p3的姓名、年龄信息。
		p3.show();		
	}
}

第7关:static关键字

​ 本关任务:通过static关键字定义类成员和类方法

//账户类的定义
class Account{
	//定义静态数据成员minBalance(double类型),记录账户最低余额,并初始化为0.0
	static double minBalance=0.0;
	//定义静态数据成员count(int类型),记录账户数量,并初始化为0
	static int count=0;
	private String accNo;
	private String accName;
	private double balance;
	//构造方法
	public Account(String accNo,String accName,float balance) {
		count++;		//账户数加1
		this.accNo = accNo;
		this.accName = accName;
		this.balance = balance;
	}
	//存款方法
	public void deposit(float amount) {
		balance += amount;
	}
	//取款方法,注意取款后,账户余额不能小于账户最小余额minBalance
	public void withdraw(float amount) {
        if(balance<minBalance)
            System.out.println("余额不足,取款失败!");
        else
            balance-=amount;
	}
	//查余额方法
	public double getBalance() {
		return this.balance;
	}
	//显示账户信息方法
	public void show() {
		System.out.println("账号:" + this.accNo);
		System.out.println("姓名:" + this.accName);
		System.out.println("余额:"+ this.balance);
	}
	//定义静态方法showCount()显示当前账户数量
    public static void showCount()
    {
        System.out.println("账户数量:"+count);
    }
	//定义静态方法setMinBalance()设置账户最低余额
    public static void setMinBalance(double minBalance)
    {
        minBalance=minBalance;
    }
	//定义静态方法getMinBalance()显示账户最低余额
	public static double getMinBalance(){
		return minBalance;
	}
}
public class AccountDemo {
	public static void main(String[] args) {
		//显示当前账户数量
		Account.showCount();
		Account zs = new Account("001", "张三",1000);
		Account ls = new Account("002", "李四",500);
		//显示当前账户数量
		Account.showCount();
		zs.deposit(1000); //存款1000元
		zs.withdraw(500); //取款500元
		//显示zs账户信息
		zs.show();
		//设置账户最低余额为100
		Account.setMinBalance(100);
		//显示账户最低余额
		System.out.println("账户最低余额:"+Account.getMinBalance());	
        System.out.println("余额不足,取款失败!");	
		zs.withdraw(1450);
		zs.show(); //显示账户信息
	}
}

第8关:对象成员:通过组合定义新的类

​ 本关任务:定义一个线段类Line,该类中有对象成员startPoint和endPoint,他们是Point类对象成员。通过该任务掌握如何通过组合实现代码重用,就像如何通过零部件组装产品

class Point {
	private double x;
	private double y;
	//构造方法,和类同名
	public Point(double x, double y) { 
		this.x = x;
		this.y = y;
	}
	//设置横坐标X方法
	public void setX(double x) {
		this.x = x;
	}
	//设置纵坐标Y方法
	public void setY(double y){
		this.y = y;
	}
	
	//获得横坐标X的方法
	public double getX() {
		return x;
	}
	//获得纵坐标Y的方法
	public double getY(){
		return y;
	}
	//获得点到原点的距离
	public double getDistance() {
		double distance = 0;
		distance = Math.sqrt(x*x + y*y); //数学类Math的静态方法sqrt:开根号
		return distance;
	}
}
class Line{
	// 定义Point类型的成员变量startPoint,表示该直线的起点
	Point startPoint;
	// 定义Point类型的成员变量endPoint,表示该直线的终点
	Point endPoint;
	// 定义构造方法1,通过起点和终点初始化直线Line的成员变量
	Line(Point p1, Point p2) { 
		startPoint = p1;
		endPoint = p2;
	}
	//定义构造方法2,通过起点坐标x1,y1和终点坐标x2,y2初始化Line的成员变量
	Line(double x1, double y1, double x2, double y2) { 
		Point a=new Point(x1,y1);
		Point b=new Point(x2,y2);
		startPoint=a;
		endPoint=b;
		
	}
	//求线段长度方法
	double getLength() {
		double x =startPoint.getX()-endPoint.getX();			//X和Y是私密的
		double y =startPoint.getY()-endPoint.getY();
		// 通过Math.sqrt()方法求直线的长度
		double length = Math.sqrt(x*x+y*y); 
		return length;
	}	
}

public class LineTest { // 定义一个类表示二维平面上的“直线”(Line)

	public static void main(String[] args) {
		Point p1 = new Point(1,1);
		Point p2 = new Point(2,2);
		// 根据p1,p2创建并初始化一个Line对象line1
		Line line1 = new Line(p1,p2);
		System.out.printf("%8.3f\n",line1.getLength());
		// 通过构造方法2创建一个表示(3,3)和(4,4)之间的直线line2。
		Line line2 = new Line(3,3,4,4);
		System.out.printf("%8.3f\n",line2.getLength());
	}
}

第9关:包机制:package和import

​ 本关任务:在一个包里定义了Point类,在当前代码包里定义个线段类Line,它使用另外一个包里Point类,然后创建两个Line类对象(及两个线段line1和line2),并求出它们的长度。通过本任务掌握如何实现不同代码资源的分类存放,如何访问其他位置(包)的代码资源

package myPackage;
//点类Point的定义,特别注意为什么前面要加上public修饰,去掉又会如何?
public class Point {
	private double x;
	private double y;
	//构造方法,和类同名
	public Point(double x, double y) { 
		this.x = x;
		this.y = y;
	}
	//设置横坐标X方法
	public void setX(double x) {
		this.x = x;
	}
	//设置纵坐标Y方法
	public void setY(double y) {
		this.y = y;
	}	
	//获得横坐标X的方法
	public double getX() {
		return x;
	}
	//获得纵坐标Y的方法
	public double getY() {
		return y;
	}	
	//获得点到原点的距离
	public double getDistance() {
		double distance = 0;
		distance = Math.sqrt(x*x + y*y); //数学类Math的静态方法sqrt:开根号
		return distance;
	}
}
package step9;
//导入myPackage的相关类
import myPackage.Point;
class Line{
	// 定义Point类型的成员变量startPoint,表示该直线的起点
	Point startPoint;
	// 定义Point类型的成员变量endPoint,表示该直线的终点
	Point endPoint;	
	// 定义构造方法1,通过起点和终点初始化直线Line的成员变量
	Line(Point p1, Point p2) { 
		startPoint = p1;
		endPoint = p2;		
	}
	//定义构造方法2,通过起点坐标x1,y1和终点坐标x2,y2初始化Line的成员变量
	Line(double x1, double y1, double x2, double y2) { 
		Point a = new Point(x1,y1);
		Point b = new Point(x2,y2);
		startPoint = a;
		endPoint = b;		
	}
	//求线段长度方法
	double getLength() {
		//得到线段两点的横坐标之差和纵坐标之差
		double x = startPoint.getX()-endPoint.getX();
		double y = startPoint.getY()-endPoint.getY();
		// 通过Math.sqrt()方法求直线的长度
		double length =  Math.sqrt(x*x+y*y); 
		return length;
	}	
}
//定义一个类表示二维平面上的“直线”(Line)
public class LineTest { 
	public static void main(String[] args) {
		Point p1 = new Point(1,1);
		Point p2 = new Point(2,2);
		// 根据p1,p2创建并初始化一个Line对象line1
		Line line1 = new Line(p1,p2);
		System.out.printf("%8.3f\n",line1.getLength());
		// 通过构造方法2创建一个表示(3,3)和(4,4)之间的直线line2。
		Line line2 = new Line(0,0,3,4);
		System.out.printf("%8.3f\n",line2.getLength());
	}
}

推荐阅读