PDA

View Full Version : [Java] Giải phương trình bậc 2 bằng OPP



D.Max
28-10-2012, 09:55 PM
ĐỀ BÀI: Giải phương trình bậc 2 bằng lập trình hướng đối tượng

mình mới học java được vài ngày, chia sẻ cho các bạn mới học về hướng đối tượng.
còn những pro thì đừng ném gạch nhé. Y(:D



import java.util.Scanner;
class phuongtrinh
{
public float a,b,c;
double x1,x2;
double delta;
Scanner input=new Scanner(System.in);
public void nhap()
{
System.out.print("nhap a: ");
this.a=input.nextFloat();
System.out.print("nhap b: ");
this.b=input.nextFloat();
System.out.print("nhap c: ");
this.c=input.nextFloat();
}
public double tinhdelta()
{
delta=((Math.pow(b, 2))-4*a*c);
return delta;
}
public double nghiemduynhat()
{
x1=-c/b;
return x1;
}
public double nghiemkep()
{
x1=-b/(2*a);
return x1;
}
public void nghiemphanbiet()
{
x1=((-b+Math.sqrt(delta))/(2*a));
x2=((-b-Math.sqrt(delta))/(2*a));
System.out.println("x1= "+x1);
System.out.println("x2= "+x2);
}
}

class dieukien
{
phuongtrinh pt=new phuongtrinh();
public void nhappt()
{
pt.nhap();
}
public void kiemtra()
{
if(pt.a==0)
{
if(pt.b==0)
{
System.out.print("phuong trinh vo so nghiem");
}
else
{

System.out.print("phuong trinh co nghiem duy nhat: "+pt.nghiemduynhat());
}
}
else
{
if (pt.tinhdelta()<0)
{
System.out.print("phuong trinh vo nghiem");
}

else
{
if(pt.tinhdelta()==0)
{
System.out.print("phuong trinhg co nghiem kep: "+pt.nghiemkep());
}
else
{
System.out.println("phuong trinh co 2 nghiem phan biet: ");
pt.nghiemphanbiet();
}
}
}
}
}
public class phuongtrinhbac2
{
public static void main(String[] args)
{
dieukien dk=new dieukien();
dk.nhappt();
dk.kiemtra();
}
}

Wazi Armstrong
28-10-2012, 10:13 PM
1. Cấu trúc dở tệ
2. Nếu các pro ko ném gạch thì bạn bỏ qua câu 1, coi như chưa nói gì

D.Max
28-10-2012, 10:24 PM
1. Cấu trúc dở tệ
2. Nếu các pro ko ném gạch thì bạn bỏ qua câu 1, coi như chưa nói gì

uk, thì mình mới nhập môn, mình đồng ý là dở tệ. Mình chỉ chia sẻ chút cho những bạn mới học về opp thôi.
Mình rất mong nhận được mọi lời góp ý.
Bạn thấy chỗ nào ko tốt có thể chỉ giùm mình. Chứ mới lên đã ném tạ như vậy có mất thiện cảm quá ko

Wazi Armstrong
28-10-2012, 10:53 PM
uk, thì mình mới nhập môn, mình đồng ý là dở tệ. Mình chỉ chia sẻ chút cho những bạn mới học về opp thôi.
Mình rất mong nhận được mọi lời góp ý.
Bạn thấy chỗ nào ko tốt có thể chỉ giùm mình. Chứ mới lên đã ném tạ như vậy có mất thiện cảm quá ko

Với mình chia sẻ kinh nghiệm đồng nghĩa với ném gạch. Mình đã post bài lên thì sẵn sàng đợi người khác ném gạch. Như thế mới nhớ lâu đc. Vết đau thường nhớ lâu mà (8-)>

Bài của bạn là Giải phương trình Bậc 2, sử dụng phương pháp lập trình hướng đối tượng đúng không.

Vậy cứ coi tất cả là đối tượng đi
1. Phương thức main thường không nói đến trong thiết kế vì nó chỉ như chìa khóa để khởi động trong chương trình.
2. Có thể hình dung ra chính ta sẽ có (các) lớp là:
2.1 Chương trình giải phương trình bậc 2 (TwoDegreeEquationSolver) Lớp này có hàm khởi tạo với 3 tham số chính là 3 hệ số a, b, c của phương trình.
Phương thức solve();
2.2 Do kết quả của PTB2 có nhiều trường hợp nên đầu ra có thể tạo 1 class riêng cho nó, gọi là Result đi
Lớp Result sẽ có phương thức hasRoot() để kiểm tra xem phương trình có nghiệm hay không và phương thức getRoots() trả về một mảng là nghiệm của phương trình (mảng có thể có 0, 1, hoặc 2 phần tử, 0 trong trường hợp ko có nghiệm)
3. Hàm main() sẽ tiến hành đọc dữ liệu người dùng nhập vào, rồi khởi tạo 1 thể hiện của TwoDegreeEquationSolver, solve rồi nhận lấy kết quả ở đầu ra và xuất trả lại người dùng.
Thiết kế này không phải là tối ưu nhưng ít ra nó cũng dùng lại được cái core của chương trình (solve-> Result), bạn có thể đem nó cho vào 1 chương trình lớn hơn mà không phải sửa gì.

Nhược điểm trong thiết kế của bạn
1. Gộp chung xử lí IO với logic. Class phươngtrinh của bạn lại tồn tại phương thức nhap() ??? Một số trường hợp mình đã gặp trên diễn đàn này: sinhvien.nhap(); nguoi.nhap() rất vô lí!!!
2. Logic bạn rải rác khắp nơi và thường không đúng chức năng. Ví dụ trong hàm main(), tại sao việc giải một phương trình bậc 2 lại bắt đầu bằng việc tạo 1 đối tượng điều kiện??? rồi thì đối tượng này lại nhập, nhập cái gì??? trong khi đối tượng phương trình lại chẳng thấy đâu... Trong dieukien.kiemtra() tại sao lại có in kết quả???

Lời kết:
Lập trình hướng đối tượng sinh ra với mục đích làm đơn giản hóa logic, làm cho mã lệnh chương trình gần với thực tế hơn. Vì thế khi bạn lập trình hướng đối tượng, hãy suy nghĩ như 1 con người, đừng cố nghĩ như 1 cái máy.

Thân!
PS: Lâu lắm rồi không viết bài dài. Sắp đến bóng đá nên vội không format đẹp được :(|

D.Max
28-10-2012, 11:19 PM
Với mình chia sẻ kinh nghiệm đồng nghĩa với ném gạch. Mình đã post bài lên thì sẵn sàng đợi người khác ném gạch. Như thế mới nhớ lâu đc. Vết đau thường nhớ lâu mà (8-)>

Bài của bạn là Giải phương trình Bậc 2, sử dụng phương pháp lập trình hướng đối tượng đúng không.

Vậy cứ coi tất cả là đối tượng đi
1. Phương thức main thường không nói đến trong thiết kế vì nó chỉ như chìa khóa để khởi động trong chương trình.
2. Có thể hình dung ra chính ta sẽ có (các) lớp là:
2.1 Chương trình giải phương trình bậc 2 (TwoDegreeEquationSolver) Lớp này có hàm khởi tạo với 3 tham số chính là 3 hệ số a, b, c của phương trình.
Phương thức solve();
2.2 Do kết quả của PTB2 có nhiều trường hợp nên đầu ra có thể tạo 1 class riêng cho nó, gọi là Result đi
Lớp Result sẽ có phương thức hasRoot() để kiểm tra xem phương trình có nghiệm hay không và phương thức getRoots() trả về một mảng là nghiệm của phương trình (mảng có thể có 0, 1, hoặc 2 phần tử, 0 trong trường hợp ko có nghiệm)
3. Hàm main() sẽ tiến hành đọc dữ liệu người dùng nhập vào, rồi khởi tạo 1 thể hiện của TwoDegreeEquationSolver, solve rồi nhận lấy kết quả ở đầu ra và xuất trả lại người dùng.
Thiết kế này không phải là tối ưu nhưng ít ra nó cũng dùng lại được cái core của chương trình (solve-> Result), bạn có thể đem nó cho vào 1 chương trình lớn hơn mà không phải sửa gì.

Nhược điểm trong thiết kế của bạn
1. Gộp chung xử lí IO với logic. Class phươngtrinh của bạn lại tồn tại phương thức nhap() ??? Một số trường hợp mình đã gặp trên diễn đàn này: sinhvien.nhap(); nguoi.nhap() rất vô lí!!!
2. Logic bạn rải rác khắp nơi và thường không đúng chức năng. Ví dụ trong hàm main(), tại sao việc giải một phương trình bậc 2 lại bắt đầu bằng việc tạo 1 đối tượng điều kiện??? rồi thì đối tượng này lại nhập, nhập cái gì??? trong khi đối tượng phương trình lại chẳng thấy đâu... Trong dieukien.kiemtra() tại sao lại có in kết quả???

Lời kết:
Lập trình hướng đối tượng sinh ra với mục đích làm đơn giản hóa logic, làm cho mã lệnh chương trình gần với thực tế hơn. Vì thế khi bạn lập trình hướng đối tượng, hãy suy nghĩ như 1 con người, đừng cố nghĩ như 1 cái máy.

Thân!
PS: Lâu lắm rồi không viết bài dài. Sắp đến bóng đá nên vội không format đẹp được :(|
sau lời nhận xét này của bạn thực sự mình rút ra rất nhiều điều! rất cảm ơn bạn! (:-*)

mr.quang
30-10-2012, 01:56 AM
Thực ra chẳng có một quy định phải chia thành bao nhiêu class. Nó phụ thuộc và trình độ, năng lực và yêu cầu đề bài hay sở thích. Nhưng thiết nghĩ đã là lập trình hướng đối tượng thì cái gì thì cũng xoay quanh đối tượng ra cả. Nếu chỉ là các hàm, các biến và class chỉ để chạy được thì nó chẳng có ý nghĩa gì cả về lập trình hướng đối tượng cả. Bạn thấy đấy, đơn giản là trong java có class về String thì các đối tượng thuộc lớp này thì cũng phải có các biến và phương thức( hàm) liên quan đến xử lí xâu như phương thức gán xâu, tìm xâu, ghép xâu, cộng xâu...Tương tự như thể class sinh viên có phương thức đi học chẳng hạn, hay thuộc tính tên trường lớp đại học gì đấy, chứ không thể lấy đâu ra phương thức xách xô, vác xi như của class đại loại thợ xây chẳng hạn ..:D.

duongpv
04-11-2012, 11:26 AM
1. Cấu trúc dở tệ
2. Nếu các pro ko ném gạch thì bạn bỏ qua câu 1, coi như chưa nói gì

Đồng ý với pro này, cấu trúc ko tốt tý nào :D
Mình có chút ý kiến thế này :
- Thứ nhất, một đặc trưng của hướng đối tượng là che dấu mã nguồn của đối tượng
-> các thuộc tính, phương thức của class nên đặt private hết, rất hạn chế đặt public (trừ các lớp kiểu static hoặc làm factory..)
- Thứ hai, trong một class, rất hạn chế truy cập trực tiếp thuộc tính, nên truy cập qua các phương thức get, set
- Thứ ba, với một bài cơ bản để học thuật toán thế này, không nhất thiết làm OOP làm gì cho cồng kềnh (:))

Muốn nghiên cứu OOP, nên đọc -> biết -> hiểu. Sau đó tự nghĩ ra một bài toán để áp dụng mấy cái mình đã hiểu về OOP

Đôi lời chia sẻ (:P)

congnghi100
27-04-2013, 12:38 PM
bài này nhập text zo thì sao ta @@

vipboycuti
23-08-2013, 09:26 AM
bài này mình sẽ làm qua ko có nhiều điều kiện và chia làm 2 class
class 1

public class PhuongTrinhBac2 {
double a,b,c;
// khai bao phương thức giải phương trình
public void GiaiPT()
{
double delta, n1, n2;
delta = b*b - 4*a*c;
if(delta<0){
System.out.println("Phương trình vô nghiệm");
}
else if(delta==0){
n1 = n2 = -b/(2*a);
System.out.println("Phương trình có nghiệm kép "
+ "\nx1 = x2 =" + n1);
}
else{//delta lớn hơn 0
n1 = (-b + Math.sqrt(delta))/(2*a);
n2 = (-b - Math.sqrt(delta))/(2*a);
System.out.println("Phương trình có 2 nghiệm phân biệt"
+ "\nX1 = " + n1 + "\nX2 = " + n2);
}
}

}


class 2 chứa hàm main

public class demo_ptb2 {
public static void main(String[] args)
{
//Tạo đối tượng của lớp PhuongTrinhBac2
PhuongTrinhBac2 ptb2 = new PhuongTrinhBac2();
Scanner nhap = new Scanner(System.in);
System.out.println("Chương trình giải Phương trình bậc2");
System.out.println("Mời nhập a= ");
ptb2.a = nhap.nextDouble();
System.out.println("Mời nhập b= ");
ptb2.b = nhap.nextDouble();
System.out.println("Mời nhập c= ");
ptb2.c = nhap.nextDouble();
//gọi phương thức GiaiPT()
ptb2.GiaiPT();
}
}

Wazi Armstrong
23-08-2013, 11:54 PM
bài này mình sẽ làm qua ko có nhiều điều kiện và chia làm 2 class
class 1

public class PhuongTrinhBac2 {
double a,b,c;
// khai bao phương thức giải phương trình
public void GiaiPT()
{
double delta, n1, n2;
delta = b*b - 4*a*c;
if(delta<0){
System.out.println("Phương trình vô nghiệm");
}
else if(delta==0){
n1 = n2 = -b/(2*a);
System.out.println("Phương trình có nghiệm kép "
+ "\nx1 = x2 =" + n1);
}
else{//delta lớn hơn 0
n1 = (-b + Math.sqrt(delta))/(2*a);
n2 = (-b - Math.sqrt(delta))/(2*a);
System.out.println("Phương trình có 2 nghiệm phân biệt"
+ "\nX1 = " + n1 + "\nX2 = " + n2);
}
}

}


class 2 chứa hàm main

public class demo_ptb2 {
public static void main(String[] args)
{
//Tạo đối tượng của lớp PhuongTrinhBac2
PhuongTrinhBac2 ptb2 = new PhuongTrinhBac2();
Scanner nhap = new Scanner(System.in);
System.out.println("Chương trình giải Phương trình bậc2");
System.out.println("Mời nhập a= ");
ptb2.a = nhap.nextDouble();
System.out.println("Mời nhập b= ");
ptb2.b = nhap.nextDouble();
System.out.println("Mời nhập c= ");
ptb2.c = nhap.nextDouble();
//gọi phương thức GiaiPT()
ptb2.GiaiPT();
}
}

Lâu lâu không vào forum.
Có thể nói ngắn gọn thế này: Bạn viết chương trình này bằng C rồi "ánh xạ 1 - 1" sang Java.
Mạng wifi câu chùa lag không viết dài đc, sorry nhé. Đọc lại 2 note của mình ở bài viết trước, code của bạn cũng dính đấy. :D

Sun of Wind
21-10-2014, 09:09 AM
Với mình chia sẻ kinh nghiệm đồng nghĩa với ném gạch. Mình đã post bài lên thì sẵn sàng đợi người khác ném gạch. Như thế mới nhớ lâu đc. Vết đau thường nhớ lâu mà (8-)>

Bài của bạn là Giải phương trình Bậc 2, sử dụng phương pháp lập trình hướng đối tượng đúng không.

Vậy cứ coi tất cả là đối tượng đi
1. Phương thức main thường không nói đến trong thiết kế vì nó chỉ như chìa khóa để khởi động trong chương trình.
2. Có thể hình dung ra chính ta sẽ có (các) lớp là:
2.1 Chương trình giải phương trình bậc 2 (TwoDegreeEquationSolver) Lớp này có hàm khởi tạo với 3 tham số chính là 3 hệ số a, b, c của phương trình.
Phương thức solve();
2.2 Do kết quả của PTB2 có nhiều trường hợp nên đầu ra có thể tạo 1 class riêng cho nó, gọi là Result đi
Lớp Result sẽ có phương thức hasRoot() để kiểm tra xem phương trình có nghiệm hay không và phương thức getRoots() trả về một mảng là nghiệm của phương trình (mảng có thể có 0, 1, hoặc 2 phần tử, 0 trong trường hợp ko có nghiệm)
3. Hàm main() sẽ tiến hành đọc dữ liệu người dùng nhập vào, rồi khởi tạo 1 thể hiện của TwoDegreeEquationSolver, solve rồi nhận lấy kết quả ở đầu ra và xuất trả lại người dùng.
Thiết kế này không phải là tối ưu nhưng ít ra nó cũng dùng lại được cái core của chương trình (solve-> Result), bạn có thể đem nó cho vào 1 chương trình lớn hơn mà không phải sửa gì.

Nhược điểm trong thiết kế của bạn
1. Gộp chung xử lí IO với logic. Class phươngtrinh của bạn lại tồn tại phương thức nhap() ??? Một số trường hợp mình đã gặp trên diễn đàn này: sinhvien.nhap(); nguoi.nhap() rất vô lí!!!
2. Logic bạn rải rác khắp nơi và thường không đúng chức năng. Ví dụ trong hàm main(), tại sao việc giải một phương trình bậc 2 lại bắt đầu bằng việc tạo 1 đối tượng điều kiện??? rồi thì đối tượng này lại nhập, nhập cái gì??? trong khi đối tượng phương trình lại chẳng thấy đâu... Trong dieukien.kiemtra() tại sao lại có in kết quả???

Lời kết:
Lập trình hướng đối tượng sinh ra với mục đích làm đơn giản hóa logic, làm cho mã lệnh chương trình gần với thực tế hơn. Vì thế khi bạn lập trình hướng đối tượng, hãy suy nghĩ như 1 con người, đừng cố nghĩ như 1 cái máy.

Thân!
PS: Lâu lắm rồi không viết bài dài. Sắp đến bóng đá nên vội không format đẹp được :(|
pro viết code giúp mình coi được không mới nhập môn nên hơi khó hiểu