以下为个人学习笔记和习题整理
课程:面向对象程序设计 ——Java 语言
- 浙江大学 - 翁恺 @ 中国大学 MOOC
https://www.icourse163.org/course/ZJU-1001542001

# 课堂笔记

# 用类制造对象

对象是实体,需要被创建,可以为我们做事情
类是规范,根据类的定义来创建对象

  • 对象(这只猫)
    表达东西或事件
    运行时响应消息(提供服务)

  • 类(猫)
    定义所有猫的属性
    就是 Java 中的类型
    可以用来定义变量

graph TD
	A[类] --> |定义了|B[对象]
	B --> |是...的实体|A

对象 = 属性 + 服务
数据:属性或状态
操作:函数

把数据和对数据的操作放在一起 ➡️ 封装

Gcluster_0操作数据数据
创建对象
new VendingMachine();
VendingMachine v= new VendingMachine()

对象变量是对象的管理者

v.insertMoney(10);
v.getFood();

. 运算符让对象做事

# 成员变量和成员函数

  • 成员变量:类定义的对象中所具有的变量。
    每个对象有自己的变量,和同一个类的其他对象是分开的。

在函数中可以直接写成员变量的名字来访问成员变量。

函数是通过对象来调用的。
v.insertMoney()insertMoney() 内部的成员变量指的是 v 的成员变量。

this 是成员函数的一个特殊的固有的本地变量,它表达了调用这个函数的那个对象。
通过 . 运算符调用某个对象的函数。
在成员函数内部直接调用自己 this 的其他函数,不需要额外加 this.

成员变量的生存期是对象的生存期,作用域是类内部的成员函数。

写在类里的成员变量,只是一个声明,变量并不在那里,变量不在类里,变量在每一个对象里。

  • 本地变量:定义在函数内部的变量。
    本地变量的生存期和作用域都是函数内部。

# 对象初始化

Java 提供了多种手段来保障对象创建时的初始化,包括给每个成员变量默认的 0 值、定义初始化和构造函数。

# 成员变量定义初始化

  • 成员变量在定义的地方就可以给出初始值
  • 没有给出初始值的成员变量会自动获得 0
  • 对象变量的 0 值表示没有管理任何对象,也可以主动给 null
  • 定义初始化可以调用函数,甚至可以使用已经定义的成员变量

# 构造函数

与类同名,没有返回值类型。

# 函数重载

一个类可以有多个构造函数,只要它们的参数表不同

创建对象的时候,给出不同的参数值,就会自动调用不同的构造函数

一个类里的同名,但参数表不同的函数构成了重载关系

通过 this() 还可以调用其他构造函数,但是只能调用无参数构造函数,且只能放在构造函数内的第一句,只能调用一次。

# 课内项目

# 画形状

MyPic.java
package shapes;
public class MyPic {
	public static void main(String[] args) 
	{
		Picture pic = new Picture(1000,1000);
		Circle c1 = new Circle(500,500,260);
		Circle c2 = new Circle(500,500,250);
		Circle c3 = new Circle(500,500,125);
		Triangle t1 = new Triangle(500, 250, 283, 625, 716, 625);
		Triangle t2 = new Triangle(500, 750, 283, 375, 716, 375);
		pic.add(c1);
		pic.add(c2);
		pic.add(c3);
		pic.add(t1);
        pic.add(t2);
		pic.draw();	
	}
}
Picture.java
package shapes;
import java.awt.Graphics;
import java.util.ArrayList;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Picture extends JFrame {
	private static final long serialVersionUID = 1L;
	private int width;
	private int height;
	
	private ArrayList<Shape> listShape = new ArrayList<Shape>();
	
	private class ShapesPanel extends JPanel {
		private static final long serialVersionUID = 1L;
		@Override
		protected void paintComponent(Graphics g) {
			super.paintComponent(g);
			for ( Shape s : listShape )
			{
				s.draw(g);
			}			
		}
		
	}
	
	public void add(Shape s)
	{
		listShape.add(s);
	}
	public Picture(int width, int height)
	{
		add(new ShapesPanel());
		this.setDefaultCloseOperation(EXIT_ON_CLOSE);
		this.width = width;
		this.height = height;
	}
	
	public void draw()
	{
		setLocationRelativeTo(null);
		setSize(width, height);
		setVisible(true);
	}
}
Shape.java
package shapes;
import java.awt.Graphics;
public abstract class Shape {
	
	public abstract void draw(Graphics g);
	
}
Circle.java
package shapes;
import java.awt.Graphics;
public class Circle extends Shape {
	private int x;
	private int y;
	private int radius;
	
	public Circle(int x, int y, int radius)
	{
		this.x = x;
		this.y = y;
		this.radius = radius;
	}
	@Override
	public void draw(Graphics g) {
		g.drawOval(x-radius, y-radius, radius*2, radius*2);
	}
}
Line.java
package shapes;
import java.awt.Graphics;
public class Line extends Shape {
	private int x1;
	private int y1;
	private int x2;
	private int y2;
	
	public Line(int x1, int y1, int x2, int y2)
	{
		this.x1 = x1; this.y1 = y1;
		this.x2 = x2; this.y2 = y2;
	}
	
	@Override
	public void draw(Graphics g) {
		g.drawLine(x1, y1, x2, y2);
	}
}
Rectangle.java
package shapes;
import java.awt.Graphics;
public class Rectangle extends Shape {
	private int x;
	private int y;
	private int width;
	private int height;
	
	public Rectangle(int x, int y, int width, int height) {
		this.x = x;
		this.y = y;
		this.width = width;
		this.height = height;
	}
	@Override
	public void draw(Graphics g) {
		g.drawRect(x, y, width, height);
	}
}
Triangle.java
package shapes;
import java.awt.Graphics;
public class Triangle extends Shape {
	private int[] x = new int[3];
	private int[] y = new int[3];
	
	public Triangle(int x1, int y1, int x2, int y2, int x3, int y3)
	{
		x[0] = x1; x[1] = x2; x[2] = x3;
		y[0] = y1; y[1] = y2; y[2] = y3;
	}
	
	@Override
	public void draw(Graphics g) {
		g.drawPolygon(x, y, x.length);
	}
}

# 自动售货机

public class VendingMachine {
	int price = 80;
	int balance = f();
	int total;
	
	VendingMachine() // 构造函数
	{
		total = 0;
	}
	
	VendingMachine(int price) // 函数重载
	{
		this(); // 位于第一行,调用无参数构造函数
		this.price = price;
	}
	
	int f()
	{
		return 10;
	}
	
	void showPrompt()
	{
		System.out.println("Welcome");
	}
	
	void insertMoney(int amount) 
	{
		balance = balance + amount;
	}
	
	void showBalance()
	{
		System.out.println(balance);
		// System.out.println(this.balance);
	}
	
	void getFood()
	{
		if (balance >= price)
		{
			System.out.println("Here you are.");
			balance = balance - price;
			total = total + price;
		}
	}
	
	public static void main(String[] args) {
		VendingMachine vm = new VendingMachine();
		vm.showPrompt();
		vm.showBalance();
		vm.insertMoney(100);
		vm.getFood();
		vm.showBalance();
		
		VendingMachine vm1 = new VendingMachine(100);
		vm1.insertMoney(200);
		vm.showBalance();
		vm1.showBalance();
		
	}
}

# 课堂讨论

  1. 函数重载与类型自动转换
    在零基础学 Java 中曾经提到过一个类型自动转换的事情。就是如果一个地方,比如函数的参数需要的是比较宽的类型的数据,比如 double 就比 int 来得宽,那么如果调用函数的时候给出了 int 值,是会被自动转换成 double 去调用函数的。

    现在,如果有两个函数重载,一个是 double ,一个是 int ,还会发生类型自动转换吗?

    写一个测试程序来试一下,告诉大家结果吧。

存在两个重载函数并不会发生类型自动转换,程序会自动寻找对应的重载函数
只存在一个比较窄的数据类型的重载函数时,程序会报错
只存在一个比较宽的数据类型的重载函数时,程序会自动转换

import java.util.Scanner;
 
public class Main {
    public static class Test {
        Test(double digit){
            System.out.println ( digit );
        }
        Test(int digit){
            System.out.println ( digit );
        }
    }
    public static void main(String[] args) {
        Scanner input = new Scanner ( System.in );
        Test t0 = new Test ( input.nextInt () );
    }
}
阅读次数

请我喝[茶]~( ̄▽ ̄)~*

Ruri Shimotsuki 微信支付

微信支付

Ruri Shimotsuki 支付宝

支付宝

Ruri Shimotsuki 贝宝

贝宝