Override constructor trong java?

public class pet1 {
    private String name;

    public pet1(String name) {
        this.name = name;
    }
}
//class 2
public class pet2 extends pet1 {

    public pet2() {
        //
    }
}

bây giờ tại pet2 mình muốn đn lại constructor thì phải làm sao , đọc trên mạng thì toàn thấy nó viết thế này :

public pet2(String name) {
        super(name);
    }

tại sao vậy

từ khoá super trong java chỉ lớp cha (Superclass). nếu bạn muốn định nghĩa lại constructor của lớp con sử dụng constructor của lớp cha thì bạn dùng super(name). Trong trường hợp của bạn constructor của lớp con được viết như sau:
public class pet2 extends pet1 {
private String otherParameter;//thêm thuộc tính khác cho lớp con
public pet2(String name, String otherParameter) {
//
super(name);
this.otherParameter = otherParameter;//gán thuộc tính
}
}

có cách nào không gọi đến contructor của lớp cha mà vẫn đn được hàm dựng của lớp con không…
nếu không thì vì sao lại không được…

tất nhiên là được rồi, thì bạn viết như bình thường thôi, nhưng như vậy bạn không sử dụng tính kế thừa của java

mình thử rồi nhưng nó không cho phép mình đn lại 1 constructor mới ở lớp con…

`public class pet1 {
    private String name;
    public pet1(String name) {
        this.name = name;
    }
}
//class 2
public class pet2 extends pet1 {
    public pet2() {
        //nếu mình viết thế này nó sẽ báo lỗi
    }`

Bạn ko gọi cũng được nhưng khi đó compiler sẽ tự gọi super(). Nếu compiler ko tìm được constructor nào như vậy (private?, ko có no-args constructor?) thì là compiler error (khi đó bạn phải trực tiếp gọi constructor của superclass trong constructor của subclass)

thì như vậy là nếu lớp cha đn 1 constructor , lớp con mà đn 1 constructor chính là override lại constructor ở lớp cha >>> lớp con ko thể tự tạo 1 constructor của riêng nó à , mà phải override lại constructor của lớp cha ???

2 contructor đó là khác nhau mà bạn. Bạn muốn tạo lớp con thì phải tạo lớp cha trước chứ. Chẳng phải đó mới là tính kế thừa sao :grin:

ý bạn là sao ?? ở trên mình đã tạo lớp cha rồi thì lớp con mới extends được chứ

Ý mình là tạo instance chứ ko phải khai báo định nghĩa.

This post was flagged by the community and is temporarily hidden.

nhưng thật sự mình cũng chưa hiểu tại sao bạn lại cần phải viết riêng cái constructor cho lớp con làm gì! nếu bạn không sử dụng contructor của lớp cha thì bạn extends nó để làm gì? nếu bạn không muốn sử dụng contructor của lớp cha thì bạn để pet1 là interface và ở pet2 ban không extends nừa mà implements cái pet1, khi đó bạn có thể thoải mái viết contructor cho pet2!

ừ mình cũng biết vậy nhưng mình đang tìm hiểu các đặc điểm của tính kế thừa thôi chứ không ai thiết kế lớp như vậy…

à cho mình hỏi 1 câu nữa là có thể nào hoán vị 2 đối tượng được không , trong trường hợp 2 đối tượng này là cha , con của nhau
nếu là thay đổi giá trị của đối tượng thì mình đã làm được nhưng thay đổi vùng nhớ mà đối tượng đó đang trỏ đến thì lại không được…
vd:

//pet1 là lớp cha , pet2 là lớp con
pet1 p1 = new pet1();
pet2 p2 = new pet2();

pet1 temp = p1;
p1=p2;
p2= (pet2) temp;

KHÔNG ĐƯỢC. Bạn chắc chắn sẽ bị lỗi compile ClassCastException vì compiler đã được lập trình là như vậy, không có trường hợp ép kiểu của cha về con (thường gọi là “hỗn”). Ví dụ dễ thấy nhất là: Dog kế thừa Animal, Dog là một Animal nhưng ngược lại thì không đúng.

1 Like

Khi compile hàm constructor của class con sẽ tự động gọi hàm constructor tương ứng của class cha, trong trường hợp của bạn sẽ bị lỗi compile là không tìm thấy hàm constructor tương ứng ở class cha. Vì ở class Pet1 bạn đã khai báo tường minh là chỉ có 1 hàm constructor là Pet1(String) rồi nên nó chỉ có duy nhất 1 hàm này thôi (trường hợp không khai báo thì complier sẽ tự đông tạo 1 hàm mặc định Pet1()). Như vậy, nạn muốn override lại hàm constructor không đối số trong trường hợp này thì ở class Pet1 phải định nghĩa thêm 1 hàm contructor không đối số mới được.

public class Pet1{
     public Pet1(){}
     public Pet1(String name){
        //
    }
}

Còn tại sao thì là do compiler đã bị lập trình như vậy rồi. :frowning:

1 Like

ok thanks bạn mình hiểu rồi…vậy là không có cách nào để hoán vị 2 đối tượng này phải không bạn…

Trừ khi Pet1 p2 = new Pet2() thì được (nhưng không phải là case của bạn hỏi)

package com.blogspot.vhandit.java_basic;

public class ExchangeMemoryTest {
	public static void main(String[] args) {
		Pet1 p1 = new Pet1();
		Pet1 p2 = new Pet2();
		
		System.out.println("before-p1: "+ p1.hashCode());
		System.out.println("before-p2: "+ p2.hashCode());
		
		Pet1 t = p1;
		p1 = p2;
		p2 = t;
		
		System.out.println("after-p1: "+ p1.hashCode());
		System.out.println("after-p2: "+ p2.hashCode());
	}
}

class Pet1{}
class Pet2 extends Pet1{}

Kết quả sẽ là:

before-p1: 366712642
before-p2: 1829164700
after-p1: 1829164700
after-p2: 366712642

Nó khác nhau hoàn toàn mà bạn 1 cái là khai báo vùng nhớ mà đối tượng trỏ tới là kiểu dữ liệu pet1 và 1 cái là kiểu dữ liệu pet2 chẳng qua do thằng pet2 là con kế thừa nên đương nhiên vùng nhớ được cấp phát cho 1 đối tượng pet2 sẽ đủ sức chứa cả 1 thằng pet1…

Xin lỗi vì mình đào mộ. Trong java thì hàm contructor không đc overide lại, super chỉ là một thủ thuật gọi lại từ thằng cha thôi! Tiêu đề tipic đã có vấn đề rồi!

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