Thắc mắc về nạp chồng constructor trong Java

Chào mọi người. Em mới bắt đầu học Java. Có một bài tập thực hành như sau:

"Tạo một lớp SanPham gồm có ba thuộc tính là tên, giá và giảm giá. Lớp cũng gồm hai phương thức là nhập và xuất thông tin ra màn hình. Thông tin xuất ra màn hình gồm:

  • Tên sản phẩm.
  • Đơn giá.
  • Giảm giá. "

Em đã tham khảo cách giải quyết bài tập trên, như sau:

package lab4;

import java.util.Scanner;

public class SanPham {
		
	//Tao thuoc tinh cho lop SanPham
	
	public String tenSanPham;
	public double giaSanPham;
	public double giamGia;
	
	//tao constructor 
	
	SanPham(){
		
	}
	
	SanPham(String tenSanPham, double giaSanPham, double giamGia) {
		this.tenSanPham = tenSanPham;
		this.giaSanPham = giaSanPham;
		this.giamGia = giamGia;
	}

	
	//Tao phuong thuc
	
	void nhapTT() {
		System.out.println("Ten san pham: ");
		tenSanPham = new Scanner(System.in).nextLine();
		System.out.println("Don gia: ");
		giaSanPham = new Scanner(System.in).nextDouble();
		System.out.println("Giam gia: ");
		giamGia = new Scanner(System.in).nextDouble();
		
	}
	
	void xuatTT() {
		System.out.println("Ten san pham: " + tenSanPham);
		System.out.println("Don gia: " + giaSanPham);
		System.out.println("Giam gia: " + giamGia);
	}
	
	public static void main(String[] args) {
		SanPham SP = new SanPham();
		SP.nhapTT();
		SP.xuatTT();
	}
}

Nhưng khi em bỏ Constructor

SanPham(String tenSanPham, double giaSanPham, double giamGia) {
		this.tenSanPham = tenSanPham;
		this.giaSanPham = giaSanPham;
		this.giamGia = giamGia;
	}

đi thì khi chạy chương trình vẫn cho kết quả như lúc có Constructor đó.

Vậy mọi người cho em hỏi:

Constructor trên có phải thừa hay không? Vì theo như em biết thì việc nạp chồng Constructor nhằm mục đích thực hiện cùng một phương thức trên nhiều đối tượng khác nhau. Nhưng theo đoạn code trên thì chỉ có một đối tượng là SP được tạo ra thôi ạ.

Còn nếu việc tạo ra Constructor đó là bắt buộc thì mọi người giải thích giúp em ạ.

Cảm ơn mọi người. ^^

Hình như ý đồ của người này đó là nếu constructor xây dựng có truyền vào tên sản phẩm, đơn giá, giảm giá thì họ chỉ cần xuất ra thôi. Còn nếu mà truyền vào mà chưa có gì (giá trị các biến tên sản phẩm,đơn giá, giảm giá chưa cho giá trị) thì họ sẽ sử dụng hàm nhập để bổ sung các giá trị đó. Mà ở đây hàm nhập sai rồi hay sao ấy vì mấy cái biến tên sản pham chắc phải có this chứ vì là nhập cho đối tượng mà

2 Likes

Về mặt nguyên tắc tạo class cho cấu trúc đối tượng, bạn làm sai vài nguyên tắc
Phân tích nhé

package lab4;

import java.util.Scanner;

public class SanPham {
    // public property?
    public String tenSanPham;
    public double giaSanPham;
    public double giamGia;

    // Contructor không tham số, tí nói sau
    SanPham(){ }

    // Contructor 3 tham số
    SanPham(String tenSanPham, double giaSanPham, double 
giamGia) {
		this.tenSanPham = tenSanPham;
		this.giaSanPham = giaSanPham;
		this.giamGia = giamGia;
    }

    // Where are Getters and Setters? , à bạn gán property là
    // public à? :( 

    // Có thể ví dụ này nhỏ, viết hàm xử lý + main vào POJO
    // được, tuy nhiên không nên viết lung tung mà tách ra làm
    // file main riêng. Đây cũng là lý do mình không đọc được
    // code
    void nhapTT() {
		System.out.println("Ten san pham: ");
		tenSanPham = new Scanner(System.in).nextLine();
		System.out.println("Don gia: ");
		giaSanPham = new Scanner(System.in).nextDouble();
		System.out.println("Giam gia: ");
		giamGia = new Scanner(System.in).nextDouble();
		
	}
	
	void xuatTT() {
		System.out.println("Ten san pham: " + tenSanPham);
		System.out.println("Don gia: " + giaSanPham);
		System.out.println("Giam gia: " + giamGia);
	}
	
	public static void main(String[] args) {
		SanPham SP = new SanPham(); 
		SP.nhapTT();
		SP.xuatTT();
	}
}

Nhìn comment và mình sẽ giải thích
public property? : Mình thấy “lạ” khi bạn tạo POJO - Plain Old Java Object, một class mô tả cấu trúc của đối tượng, với property set public. Thông thường tạo POJO sẽ tạo property set private nhằm mục đích không cho những thằng khác truy cập vào theo cách thông thường. Tìm hiểu Access Modifier. Cách class khác muốn truy cập vào phải thông qua getter và setter nhằm mục đích bảo toàn dữ liệu trong đối tượng đó không bị set lung tung, ngoài ra ta có thể viết validate vào setter
Contructor không tham số và 3 tham số : Việc tạo 2 contructor này chả thừa đâu. Một cái không tham số để bạn có thể dùng setter gán giá trị sau. Một cái 3 tham số để set property vào ngay khi tạo object
SanPham SP = new SanPham('Bot Giat', 50000, 20);
Getters and setters? : Như mình đã nói, chuẩn khi làm pojo là phải set property private nên cần các hàm public getter setter để truy cập vào property của đối tượng đó

Vậy pojo chuẩn sẽ là

public class SanPham {
    private String tenSanPham;
    private double giaSanPham;
    private double giamGia;

    public SanPham() {}

    public SanPham(String tenSanPham, double giaSanPham, 
double giamGia) {
        this.tenSanPham = tenSanPham;
        this.giaSanPham = giaSanPham;
        this.giamGia = giamGia;
    }

    // getter cho từng property của đối tượng SanPham. Dùng 
    // cho class khác truy cập vào property

    public String getTenSanPham() {
        return this.tenSanPham;
    }

    public String getGIaSanPham() {
        return this.giaSanPham;
    }

    public String getGiamGia() {
        return this.giamGia;
    }

    // setter cho từng property của đối tượng SanPham. Dùng 
    // cho class khác truy cập vào property

    public void setTenSanPham(String tenSanPham) {
        this.tenSanPham = tenSanPham;
    }

    public void setGiaSanPham(double giaSanPham) {
        this.giaSanPham = giaSanPham;
    }

    public void setGiamGia(double giamGia) {
        this.giamGia = giamGia;
    }
}

Vậy khi bạn làm hàm nhapTT bạn có 2 lựa chọn:

  • Tạo một đối tượng SanPham dùng contructor không tham số, sau đó dùng các hàm setter để set vào đối tượng
    VD
// trong hàm main
SanPham SP = new SanPham();

// Không sử dụng hàm nhập, Scanner trong main, các setter trong main
SP.setTenSanPham("Bot Giat");
SP.setGiaSanPham(50000);
SP.setGiamGia(20);

// Sử dụng hàm nhập thì khỏi setter
  • Tạo một đối tượng SanPham dùng contructor 3 tham số, 3 tham số bên trong truyền các giá trị đã nhập trên Scanner
    VD
// trong hàm main
Scanner trong main
SanPham SP = new SanPham("Bot Giat", 50000, 20);

P/S: Trong hàm main mình đọc nhầm 2 hàm NhapTT và XuatTT không thông qua SanPham
Mình đọc thành ra vầy

NhapSP();
XuatSP();
// Mà nếu thế này thì nó bị lỗi static

Bạn nên tách ra thành 2 class, một cái thể hiện thuộc tính và phương thức của đối tượng, một cái viết hàm main nhé :laughing:

5 Likes

không sai, this có thể bỏ nếu không có local variable cùng tên

1 Like
83% thành viên diễn đàn không hỏi bài tập, còn bạn thì sao?