过去几天我一直在尝试使用Java中的Classes,从youtube上的“TheNewBoston”和java文档中了解它们。
我创建了以下场景,并就我的一些问题寻求你们的(女孩们)专业批评和深入了解。
有两个类,person和person_financial,分别是基类和子类。
人类:
public class person {
private String name;
private String sex;
private int age;
private double height;
private double weight;
private double intelligence;
// person constructor arguments order: name, height, weight, age, sex, intelligence
public person(){
this("noname",0,0,0,"undefined",5);
}
public person(String n){
this(n,0,0,0,"undefined",5);
}
public person(String n, double h){
this(n,h,0,0,"undefined",5);
}
public person(String n, double h, double w){
this(n,h,w,0,"undefined",5);
}
public person(String n, double h, double w, int a){
this(n,h,w,a,"undefined",5);
}
public person(String n, double h, double w, int a, String s){
this(n, h, w, a, filterSex(s), 5);
}
public person(String n, double h, double w, int a, String s, double i){
name = n;
height = h;
weight = w;
age = a;
sex = filterSex(s);
intelligence = i;
}
public void setName(String n){
name = n;
}
public void setHeight(double h){
height = h;
}
public void setWeight(double w){
weight = w;
}
public void setAge(int a){
age = a;
}
public void setSex(String s){
sex = filterSex(s);
}
public void setIntel(double i){
intelligence = i;
}
public String getName(){
return name;
}
public double getHeight(){
return height;
}
public double getWeight(){
return weight;
}
public int getAge(){
return age;
}
public String getSex(){
return sex;
}
public double getIntel(){
return intelligence;
}
public String getInfo(){
return String.format("Name: %s,\nSex: %s,\nAge: %d,\nIntelligence: %.2f,"
+ "\nHeight: %.2f,\nWeight: %.2f\n", name, sex, age,
intelligence, height, weight);
}
private static String filterSex(String s){
return ((s.equalsIgnoreCase("male") ||
s.equalsIgnoreCase("female")) ? s : "undefined");
}
}
person_financial class:
public class person_financial extends person {
private double monies = 0;
public void definePerson(String n, int a, String s, double i, double h, double w){
setName(n);
setAge(a);
setSex(s);
setIntel(i);
setHeight(h);
setWeight(w);
}
public person_financial() {
this(0);
}
public person_financial(double m) {
monies = m;
}
public void depositMonies(double m) {
monies += m;
}
public void withdrawlMonies(double m) {
if (m <= monies) {
monies -= m;
}
}
public double getBalance() {
return monies;
}
}
然后在主要课程中我有这个:
public class Main {
public static void main(String[] args) {
person p1 = new person("I have no Name", 180, 72, 38, "Alien", 7.2);
System.out.println(p1.getName());
person_financial pf1 = new person_financial(100.00);
pf1.depositMonies(50.02);
System.out.printf("%s has %.2f monies.\n", pf1.getName(), pf1.getBalance());
pf1.definePerson("some_name", 42, "male", 10, 180, 72);
System.out.println(pf1.getInfo());
}
}
在person_financial类中,我创建了一个名为“definePerson()”的方法,我用它来定义本来可以从'person'类的'person()'构造函数定义的所有特征。我确信有一种更专业的方法可以为子类中的基类中的变量赋值,我只是不知道任何...
另外,有没有办法从“person”类调用构造函数来定义'pf1'的特征?而不是必须,例如,手动设置每个属性,即pf1.setName(“something”); ,或pf1.setAge(1000000);等...或者有一个方法为我做,如'definePerson()'。
非常感谢任何帮助, 谢谢=)。
答案 0 :(得分:5)
使用super()
调用来调用父类的构造函数。它必须是派生类的构造函数中的第一个调用,但是你像任何其他函数一样调用它(并传入参数),它将以这种方式调用构造函数。
答案 1 :(得分:0)
通常会声明一个类'abstract'来阻止创建泛型对象 - 基于你的底层使用代码,你似乎不想要那样,那很好。请记住,您可以声明声明一个类摘要。
使用类层次结构的最佳方法是确保(流行语警报)有用层次结构中的任何类应该在层次结构中以任何方式声明(即,您应该能够从基础访问具体对象中的任何方法 - 上课(本例中的人)。
您的financial_person对象扩展了person,但理想的是拥有一个可以在高级别声明的类并以多态方式调用方法。考虑一下所有人都可以提取和存款(与你的课程不同,但与我相处一分钟)。
drawMoney方法将存在于人,但被标记为抽象 - 强制子类financial_person和regular_person实现draw_money,deposit_money等。
每个班级都有一个适合他们现实的实现(财务人员可以访问各种特殊帐户,折扣等,而regular_person会有更简单的一组 - 但仍然是相同的外部行为)。
然后你可以这样声明:
Person finPerson = new FinancialPerson(... etc.);
Person regPerson = new RegularPerson(....etc);
现在请注意,您可以执行以下代码:
finPerson.drawCash(12300.0);
regperson.drawCase(100.0);
相同的行为。
您可以拥有数千人的列表,并且不必执行if-then-else或switch语句来执行每个人的精细调整行为。
类层次结构的酸测试是这样的:“我(子类)真的'是'(超类)?”
换句话说,“我的子类是否具有超类的行为?”
如果没有,您应该仔细考虑类层次结构。有一个流行语:Liskov替换原则,我不能比罗伯特做得更好。 C. Martin - 软件设计专家之一:
http://www.objectmentor.com/resources/articles/lsp.pdf
在本文中,他展示了当你有一个不可取的层次结构时会发生什么,使用“一个正方形是一种矩形”的例子。
Google“模板方法模式”,用于有效使用继承的另一个方面的摘要。你会发现它比简单的继承更强大,大多数人认为它是正确的。
还要记住,没有一种模式可以作为一切的银弹。有些人会调用类层次结构邪恶并告诉你只使用接口;其他人会反过来说。有选择,有时它们不会很明显。
存在许多陷阱,丢失的LSP只是其中之一。其他的(仅举例)覆盖具体方法,具有未标记为final的具体类,允许“识别”字段的可变性(例如,equals / hashcode中使用的字段等)想象一下,如果银行的“客户”对象允许重置名字,或者在运行时帐号,一旦这些字段已经设置好了。)
我的答案通常与OO设计,继承等有关,而不是特定的编码问题 - 希望它对你有用。