Rắc rối tí với lớp trừu tượng (abstract) trong Java

dt2it153

Member
14/7/11
92
2
8
nhà tui ^^
mình xây dựng một lớp trừu tượng Hình chung chung, trong lớp trừu tượng này khai báo 2 phương thức tính chu vi và diện tích của hình:
PHP:
public abstract class PlaneGeometry {
    public abstract double perimeter();
    public abstract double area();

}
Sau đó mình xây dựng 3 lớp Hình vuông, hình chữ nhật, hình tròn kế thừa từ lớp trừu tượng trên, cài đặt chi tiết 2 phương thức kế thừa từ lớp PlaneGeometry:
PHP:
[COLOR="Red"]public class Square extends PlaneGeometry {[/COLOR] //bao loi la lop nay khong phai truu 
    public double perimeter(int a) {                         //tuong, k ke thua phuong thuc duoc 
        return 4*a;
    }

    public double area(int a) {
        return a*a;
    }
}
2 lớp còn lại mh cài đặt tương tự, và đây là hàm main thực thi:

PHP:
public class AbstractGeometry {
    public static void main(String[] args) {
        // TODO code application logic here
        Square mySquare = new Square();
        System.out.println("Chu vi hinh vuong: " + mySquare.perimeter(3));
        System.out.println("Dien tich hinh vuong: " + mySquare.area(3));
}
Run chạy không được. Vì có lỗi ở đoạn code mình in đỏ đó. Không hiểu lý do tại sao? Mình đã thử sửa lại ở các lớp kế thừa thành lớp trừu tượng, nhưng khi đó lại phát sinh lỗi ở hàm main. Không biết vấn đề của mình ở đâu, các bác chỉ ra giúp!
 

meocon123

New Member
24/2/11
202
11
0
Ðề: Rắc rối tí với lớp trừu tượng (abstract) trong Java

Mình thấy bạn sai ở chỗ phương thức bạn định nghĩa trong abstract class không có đối số nhưng khi bạn override thì phương thức trong lớp con lại có đối số--> Sai về tinh thần override trong Java nên nó báo lỗi thôi, chứ không liên quan gì đến abstract ở đây cả. Thân!
Chỗ sai:
public abstract double perimeter();
public double perimeter(int a) {
return 4*a;
}
Cách khắc phục: khai báo tham số cho phương thức trong lớp cha (abstract): public abstract double perimeter(int a);
 

dt2it153

Member
14/7/11
92
2
8
nhà tui ^^
Ðề: Rắc rối tí với lớp trừu tượng (abstract) trong Java

Mình thấy bạn sai ở chỗ phương thức bạn định nghĩa trong abstract class không có đối số nhưng khi bạn override thì phương thức trong lớp con lại có đối số--> Sai về tinh thần override trong Java nên nó báo lỗi thôi, chứ không liên quan gì đến abstract ở đây cả. Thân!
Chỗ sai:
public abstract double perimeter();
public double perimeter(int a) {
return 4*a;
}
Cách khắc phục: khai báo tham số cho phương thức trong lớp cha (abstract): public abstract double perimeter(int a);
ngoài lớp Square, mình còn viết thêm 2 lớp nữa là lớp cho hình chữ nhật và hình tròn, mà hình chữ nhật 2 phương thức của nó đều có 2 đối số, vậy trong lớp trừu tượng PlaneGeometry mình sẽ phải khai báo đến 4 phương thức, 2 phương thức tính chu vi và diện tích có 1 đối số, 2 phương thức tính CV và DT có 2 đối số?
 
10/7/11
540
3
18
Ðề: Rắc rối tí với lớp trừu tượng (abstract) trong Java

Thực tế cái này bạn ko cần phải thêm đối số gì cả bỏ hết đối số cũng được ,bạn chỉ cần declare trước khi sử dụng biến a thôi .
Còn Override thì ko nhất thiết phải OverWriter hết đâu , Chỉ Override 1 hoặc nhiều cái Method . Cái nào dùng thì Override định nghĩa nó lại thôi .
 

dt2it153

Member
14/7/11
92
2
8
nhà tui ^^
Ðề: Rắc rối tí với lớp trừu tượng (abstract) trong Java

Thực tế cái này bạn ko cần phải thêm đối số gì cả bỏ hết đối số cũng được ,bạn chỉ cần declare trước khi sử dụng biến a thôi .
Còn Override thì ko nhất thiết phải OverWriter hết đâu , Chỉ Override 1 hoặc nhiều cái Method . Cái nào dùng thì Override định nghĩa nó lại thôi .
Mình đã sửa lại và run được, cụ thể mình giữ nguyên lớp trừu tượng PlaneGeometry, thay đổi phần cài đặt hàm Square:
PHP:
public class Square extends PlaneGeometry {
    public int a = 2;
    public double perimeter() {
        return 4*this.a;
    }

    public double area() {
        return this.a*this.a;
    }
}
..và hàm main:
PHP:
public static void main(String[] args) {
        // TODO code application logic here
        Square mySquare = new Square();
        System.out.println("Chu vi hinh vuong: " + mySquare.perimeter());
        System.out.println("Dien tich hinh vuong: " + mySquare.area());
}
Nhưng mình muốn truyền giá trị cụ thể trong hàm main, chứ không muốn thay đổi từng giá trị trong mỗi class kế thừa từ lớp PlaneGeometry. Có cách nào không nhỉ, dùng nạp chồng (overloading)??
 

meocon123

New Member
24/2/11
202
11
0
Ðề: Rắc rối tí với lớp trừu tượng (abstract) trong Java

Thực tế cái này bạn ko cần phải thêm đối số gì cả bỏ hết đối số cũng được ,bạn chỉ cần declare trước khi sử dụng biến a thôi .
Còn Override thì ko nhất thiết phải OverWriter hết đâu , Chỉ Override 1 hoặc nhiều cái Method . Cái nào dùng thì Override định nghĩa nó lại thôi .
Bạn nói ở đây là override phương thức bình thường, còn nếu các phương thức trong lớp cha mà khai báo kiểu abstract thì lớp con kế thừa lớp đó bắt buộc phải override tất cả bạn à. Cho dù có dùng hay không.
 

meocon123

New Member
24/2/11
202
11
0
Ðề: Rắc rối tí với lớp trừu tượng (abstract) trong Java

Mình không biết mục đích của chủ pic ở đây là muốn hiểu về lớp trừu tượng hay là giải quyết bài này. Nhưng đối với mình bài tập này thì không nên dùng abstract class và method class. Theo mình chỉ nên áp dụng overload và override là được rồi, các bạn xem 2 cách giải quyết này rồi thảo luận nhé:
Thứ nhất dùng abstract:
PHP:
package ex_abstract;

public abstract class PlaneGeometry {
	public abstract double Perimeter(int a);	
	public abstract double area(int b);
	public abstract double Perimeter(int a, int b);
	public abstract double area(int a, int b);
}
PHP:
package ex_abstract;

public  class Square extends PlaneGeometry {

	@Override
	public double Perimeter(int a) {
		return 4*a;
	}

	@Override
	public double area(int b) {
		return b*b;
	}

	@Override
	public double Perimeter(int a, int b) {
		// TODO Auto-generated method stub
		return 0;
	}

	@Override
	public double area(int a, int b) {
		// TODO Auto-generated method stub
		return 0;
	}

	
}
PHP:
package ex_abstract;

public class Rectangle extends PlaneGeometry {

	@Override
	public double Perimeter(int a, int b) {
		return (a+b)*2;
	}

	@Override
	public double area(int a, int b) {
		return a*b;
	}

	@Override
	public double Perimeter(int a) {
		// TODO Auto-generated method stub
		return 0;
	}

	@Override
	public double area(int b) {
		// TODO Auto-generated method stub
		return 0;
	}
	

}
PHP:
package ex_abstract;

public class AbstractGeometry {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		Square obj = new Square();
		Rectangle rec = new Rectangle();
		System.out.println("Chu vi hinh vuong: "+obj.Perimeter(4));
		System.out.println("Dien tich hinh vuong: "+obj.area(4));
		System.out.println("Chu vi hinh chu nhat: "+rec.Perimeter(2, 4));
		System.out.println("Dien tich hinh chu nhat: "+rec.area(2, 4));
	}


}
Ở đây nếu dùng abstract method thì ta thấy trong lớp con phải ghi đè luôn những phương thức mà ta không cần đến-->Không tối ưu
 

dt2it153

Member
14/7/11
92
2
8
nhà tui ^^
Ðề: Rắc rối tí với lớp trừu tượng (abstract) trong Java

mình cũng thấy thế! :) thanks cậu nhe, meocon123!
Đây là 1 bài tập để mình hiểu rõ hơn về abstract class thôi, vì mình vừa xem xong lý thuyết phần đó nên áp dụng thử. Bản thân mình cũng đồng ý với góp ý của cậu, các lớp kế thừa từ lớp trừu tượng đó khi override thì phải override luôn cả những phương thức có trong lớp trừu tượng đó.
Nhờ thảo luận mà mình hiểu rõ thêm các vấn đề của mình, thanks all!
 
10/7/11
540
3
18
Ðề: Rắc rối tí với lớp trừu tượng (abstract) trong Java

mình cũng thấy thế! :) thanks cậu nhe, meocon123!
Đây là 1 bài tập để mình hiểu rõ hơn về abstract class thôi, vì mình vừa xem xong lý thuyết phần đó nên áp dụng thử. Bản thân mình cũng đồng ý với góp ý của cậu, các lớp kế thừa từ lớp trừu tượng đó khi override thì phải override luôn cả những phương thức có trong lớp trừu tượng đó.
Nhờ thảo luận mà mình hiểu rõ thêm các vấn đề của mình, thanks all!
Đừng có nhận định sai lầm . Không cần phải Override tất cả . Bạn bên đọc kỹ lại lý thuyết Abstract đối với class và Implement đối với Interface .
 
10/7/11
540
3
18
Ðề: Rắc rối tí với lớp trừu tượng (abstract) trong Java

Bạn nói ở đây là override phương thức bình thường, còn nếu các phương thức trong lớp cha mà khai báo kiểu abstract thì lớp con kế thừa lớp đó bắt buộc phải override tất cả bạn à. Cho dù có dùng hay không.
Mình nghĩ bạn nên đọc kỹ lại lý thuyết về Abstract đối với class và Implement đối với Interface , đừng có nhận định sai lầm cho bạn kia . Theo đó đối với Nếu khai báo Implement đối với Interface mới phải Override tất cả các method, còn đối với Abstract thì chỉ cần Override 1 hoặc tất cả các method đó . >> Đây là sai lầm là thứ nhất .
Thứ hai : Cách giải của bạn là làm hoàn toàn bình thương , mình chưa thấy cách thứ 2 đâu cả .
 
10/7/11
540
3
18
Ðề: Rắc rối tí với lớp trừu tượng (abstract) trong Java

Đây là code mình viết hình như cũng giống như bạn thôi .
public abstract class PlaneGeometry {
public abstract double perimeter(double a);
public abstract double area(double a);
}

public class Square extends PlaneGeometry {
public double a ;
@Override
public double perimeter(double a) {
return 4*a;
}

@Override
public double area(double a) {
return a*a;
}
}

public class TestJava {
public static void main(String[] args) {
// TODO code application logic here
Square mySquare = new Square();
System.out.println("Chu vi hinh vuong:" +mySquare.perimeter(2));
System.out.println("Dien tich hinh vuong:" +mySquare.area(2));
}
}
 

meocon123

New Member
24/2/11
202
11
0
Ðề: Rắc rối tí với lớp trừu tượng (abstract) trong Java

Cách 2: Không dùng gì đến abstract
PHP:
package ex_abstract;

public  class PlaneGeometry {
	public  double Perimeter(int a){
		return 0;
	}
	
	public  double area(int b){
		return 0;
	}
	public  double Perimeter(int a, int b){
		return 0;
	}
	public  double area(int a, int b){
		return 0;
	}
}
PHP:
package ex_abstract;

public  class Square extends PlaneGeometry {

	@Override
	public double Perimeter(int a) {
		return 4*a;
	}

	@Override
	public double area(int b) {
		return b*b;
	}

}
PHP:
package ex_abstract;

public class Rectangle extends PlaneGeometry {

	@Override
	public double Perimeter(int a, int b) {
		return (a+b)*2;
	}

	@Override
	public double area(int a, int b) {
		return a*b;
	}

}
PHP:
package ex_abstract;

public class AbstractGeometry {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		Square obj = new Square();
		Rectangle rec = new Rectangle();
		System.out.println("Chu vi hinh vuong: "+obj.Perimeter(4));
		System.out.println("Dien tich hinh vuong: "+obj.area(4));
		System.out.println("Chu vi hinh chu nhat: "+rec.Perimeter(2, 4));
		System.out.println("Dien tich hinh chu nhat: "+rec.area(2, 4));
	}


}
Cách này chỉ override những phương thức mình cần, không phải override tất cả, trong cách 1 lớp Square có ghi đè 1 phương thức:
@Override
public double Perimeter(int a, int b) {
// TODO Auto-generated method stub
return 0;
}
Thao tác này là bắt buộc nhưng không hề cần thiết. Còn đây là lý thuyết:
Declaring a method as abstract has two results:
The class must also be declared abstract. If a class contains an abstract
method, the class must be abstract as well.
Any child class must either override the abstract method or declare
itself abstract.
Ebook: Java in 60 minute a day, Author: Rich Raprosa, Page 242, Chapter 8
 

meocon123

New Member
24/2/11
202
11
0
Ðề: Rắc rối tí với lớp trừu tượng (abstract) trong Java

@HTP: Vậy bạn viết tiếp lớp Rectangle thừa kế từ lớp PlaneGeometry để tính chu vi và diện tích hình chữ nhật đi, 2 phương thức mỗi phương thức truyền 2 đối số, rồi bạn sẽ thấy. Thân!
 
10/7/11
540
3
18
Ðề: Rắc rối tí với lớp trừu tượng (abstract) trong Java

@HTP: Vậy bạn viết tiếp lớp Rectangle thừa kế từ lớp PlaneGeometry để tính chu vi và diện tích hình chữ nhật đi, 2 phương thức mỗi phương thức truyền 2 đối số, rồi bạn sẽ thấy. Thân!
Thấy cái gì ? Lấy tài liệu Sun ra đọc \:D/ . Bạn thử bỏ 1 cái method ( tức là không Override nó ) trong abstract rồi Override cái còn lại nó có báo lỗi ko rồi nói tiếp .

Thân .
 
10/7/11
540
3
18
Ðề: Rắc rối tí với lớp trừu tượng (abstract) trong Java

Từ hầu giờ chỉ có kế thừa đối với Interface mới phải Override tất cả , còn đối với Abstract chí 1 hoặc tất cả .
 
10/7/11
540
3
18
Ðề: Rắc rối tí với lớp trừu tượng (abstract) trong Java

Bạn có hiểu gì về Interface không. Nếu bạn không hiểu thì mình sẽ làm 1 bài so sánh 2 cái đó ( Abstract đối với class và Implement đối với Interface ) .
Hai cái này rất dễ nhầm lẫn . Còn tài liệu vô khối chúng ta phải theo chuẩn của Sun . Còn cái bạn ghi quyển gì kia mình cũng chưa xem nhưng nó ghi sai . Hoặc bạn đọc sai .
 

meocon123

New Member
24/2/11
202
11
0
Ðề: Rắc rối tí với lớp trừu tượng (abstract) trong Java

Sao cậu cứ đem lý thuyết ra mà nói không vậy, mình nói nếu phương thức trong lớp cha mà được khai báo kiểu abstract (phương thức khai báo kiểu abstract chứ không phải lớp astract), thì lớp nào thừa kế lớp cha đó bắt buộc phải ghi đè tất cả các phương thức astract đó.
 

meocon123

New Member
24/2/11
202
11
0
Ðề: Rắc rối tí với lớp trừu tượng (abstract) trong Java

Bạn có hiểu gì về Interface không. Nếu bạn không hiểu thì mình sẽ làm 1 bài so sánh 2 cái đó ( Abstract đối với class và Implement đối với Interface ) .
Hai cái này rất dễ nhầm lẫn . Còn tài liệu vô khối chúng ta phải theo chuẩn của Sun . Còn cái bạn ghi quyển gì kia mình cũng chưa xem nhưng nó ghi sai . Hoặc bạn đọc sai .
Cậu làm đi. Chứ nói lý thuyết không thì cũng khó hiểu.
 
10/7/11
540
3
18
Ðề: Rắc rối tí với lớp trừu tượng (abstract) trong Java

Để mình so sánh theo chuẩn của Sun nha . Còn VD thì vô khối .
1/ Từ khóa kế thừa
- Abstract: extend
- Interface: implements
2/ Tầm vực:
- Abstract: private/protect/public/default
- Interface: Chỉ có thể là public thôi
3/ Override:
- Abstract: Override one or all method
- Interface: Must to Overide all method .
4/ Đa thừa kế:
- Abstract: Extends đúng 1 class duy nhất
- Interface: Extends many Interface .
5/Subclass
- Abstract: Extends 1 abstract class .
- Interface: Implement many Interface .
6/ Define
- Abstract: Define/create method
- Interface: Cann't define .