A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© Miss小强 中级黑马   /  2013-5-9 15:27  /  2203 人查看  /  18 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 Miss小强 于 2013-5-10 18:16 编辑
  1. class Person {
  2. private HashSet set1=new HashSet();
  3. public HashSet getSet1() {
  4. return set1;
  5. }

  6. private Set set2=new HashSet();
  7. public HashSet getSet2() {
  8. return set2;
  9. }

  10. private Set set3=new HashSet();
  11. public Set getSet3(){
  12. return set3;
  13. }

  14. }
复制代码
请问这三种方式哪种更优雅,并说说为什么。。。

18 个回复

倒序浏览
书上看到的,他建议我们采用第三种方式,理由说了一大堆没怎么看懂。。。
求大神啊。。。
回复 使用道具 举报
额,第三种吧,可以提高扩展性,是面向接口编程的体现。set3可以指向hashSet、TreeSet(实现Set接口的都行)
回复 使用道具 举报
Miss小强 发表于 2013-5-9 15:29
书上看到的,他建议我们采用第三种方式,理由说了一大堆没怎么看懂。。。
求大神啊。。。 ...

没看懂就先记住,收藏下,慢慢就理解了
回复 使用道具 举报
曹睿翔 发表于 2013-5-9 15:40
额,第三种吧,可以提高扩展性,是面向接口编程的体现。set3可以指向hashSet、TreeSet(实现Set接口的都行 ...

Person person=new Person();
TreeSet set3=(TreeSet) person.getSet3();
System.out.println(set3);
结果: java.lang.ClassCastException: java.util.HashSet cannot be cast to java.util.TreeSet
        at cn.itcast.problem.CollectionMapTest.main(CollectionMapTest.java:14)
回复 使用道具 举报
收藏下,慢慢理解…
回复 使用道具 举报
Miss小强 发表于 2013-5-9 16:04
Person person=new Person();
TreeSet set3=(TreeSet) person.getSet3();
System.out.println(set3);

你的这个错误很正常,因为Set set3=new HashSet();set3的实例引用是HashSet,不是TreeSet,强转会出现类型转换异常。
要说面向接口的好处,用代理最好解释了,涉及到反射
比如:简化代码
String str = prop.getProperty("className");
/*配置文件中存比如className = HashSet ;当需求发生变化,person需要排序就把HashSet换成TreeSet,而不用去修改代码,修改配置文件就行了*/
Set set3=Class.forName(str).newInstance();
回复 使用道具 举报
按照我的理解,选第一种,尽管第一种也不优雅。

第二三种无法单独编译和运行,因为java编译和运行的基本单位是类,必须放在一个类里面,这又转化成第一种方式了。
回复 使用道具 举报
Miss小强 发表于 2013-5-9 16:04
Person person=new Person();
TreeSet set3=(TreeSet) person.getSet3();
System.out.println(set3);

对接口进行强转,本身属于对接口的误用。如果真的需要其他类型,那么应该使用具体类型,而不是接口类型。

接口有n多种好处,但是这些好处也是有适用范围的,不是任何环境下都有这种好处。
回复 使用道具 举报
吴超老师 发表于 2013-5-9 20:50
按照我的理解,选第一种,尽管第一种也不优雅。

第二三种无法单独编译和运行,因为java编译和运行的基本单 ...

神啊,原谅我吧,真没怎么听懂,能在解释解释吗。。。
回复 使用道具 举报
wuddd 高级黑马 2013-5-10 05:43:20
11#
Miss小强 发表于 2013-5-9 22:25
神啊,原谅我吧,真没怎么听懂,能在解释解释吗。。。

我的话没有歧义,哪句不理解,有什么疑惑,你是怎么猜测的?
回复 使用道具 举报
吴超老师 发表于 2013-5-10 05:43
我的话没有歧义,哪句不理解,有什么疑惑,你是怎么猜测的?

第一次看到帮我们答贴...顶吴老师:lol
回复 使用道具 举报
java编译和运行的基本单位是类,必须放在一个类里面。
这个我知道,但是前面那句,第二种,第三种无法单独编译?
这三种不是都在一个Person类中吗?
同时这个转换是什么意思?
是所有的情况到最后都是
返回的是一个HashSet吗?
回复 使用道具 举报
吴超老师 发表于 2013-5-10 05:43
我的话没有歧义,哪句不理解,有什么疑惑,你是怎么猜测的?

突然想到我入学测试题也有一个类似的问题,不多说,上代码:
  1. package com.itheima;

  2. /**
  3. * 要求:1、 假如我们在开发一个系统时需要对员工进行建模, 员工包含 3 个属性:姓名、工号以及工资。经理也是员工, 除了含有员工的属性外,另为还有一个奖金属性。
  4. * 请使用继承的思想设计出员工类和经理类。 要求类中提供必要的方法进行属性访问。
  5. *
  6. * @author 荣强
  7. *
  8. */
  9. public class Test1 {
  10. public static void main(String[] args) {
  11. Employee zhangsan = new Employee();
  12. zhangsan.setEmpId(1011);
  13. zhangsan.setName("张三");
  14. zhangsan.setSalary(3000f);//带着f,表示是float型数据;
  15. sop(zhangsan);
  16. sop("----------------------------------------------");
  17. Manager lisi=new Manager();
  18. lisi.setEmpId(1013);
  19. lisi.setName("李四");
  20. lisi.setSalary(4000f);
  21. lisi.setBonus(1000f);
  22. sop(lisi);
  23. sop("----------------------------------------------");
  24. <FONT color=orange><FONT color=red>Employee wangwu=new Manager();//定义父类引用,指向子类实体;
  25. wangwu.setEmpId(1014);
  26. wangwu.setName("王五");
  27. wangwu.setSalary(5000f);
  28. //这里不能调用setBonus方法,因为父类根本就没有;</FONT>
  29. </FONT>
  30. <FONT color=red>System.out.println(wangwu);</FONT>

  31. Manager manager=(Manager)wangwu;//要使用子类功能,需要强制转换;
  32. manager.setBonus(2000f);
  33. sop(manager);
  34. sop("----------------------------------------------");
  35. }
  36. //由于输出语句比较多,方便起见,定义一个带泛型的输出方法;
  37. public static <T> void sop(T t) {
  38. System.out.println(t);
  39. }
  40. }

  41. /**
  42. *
  43. * @author 荣强 员工类:有三个属性,姓名,工号,工资;
  44. * 实现Comparable接口,使得该类具有比较性,可以顺利的放入TreeSet等需要具备比较性的集合;
  45. * 如果对这种自然排序不满,我们可以自定义比较器(实现Comparator接口,或者直接用匿名内部类)
  46. * 这是一个JavaBean;满足JavaBean的规则;有无参构造函数,无重载构造函数;
  47. */
  48. class Employee implements Comparable<Employee> {
  49. private String name;
  50. private int empId;
  51. private float salary;

  52. public Employee() {
  53. super();
  54. }

  55. public String getName() {
  56. return name;
  57. }

  58. public void setName(String name) {
  59. this.name = name;
  60. }

  61. public int getEmpId() {
  62. return empId;
  63. }

  64. public void setEmpId(int empId) {
  65. this.empId = empId;
  66. }

  67. public float getSalary() {
  68. return salary;
  69. }

  70. public void setSalary(float salary) {
  71. this.salary = salary;
  72. }

  73. /**
  74. * 使用Myeclipse工具生成的方法
  75. */
  76. @Override
  77. public int hashCode() {
  78. final int prime = 31;
  79. int result = 1;
  80. result = prime * result + empId;
  81. result = prime * result + ((name == null) ? 0 : name.hashCode());
  82. result = prime * result + Float.floatToIntBits(salary);
  83. return result;
  84. }

  85. /**
  86. * 使用Myeclipse工具生成的方法
  87. */
  88. @Override
  89. public boolean equals(Object obj) {
  90. if (this == obj)
  91. return true;
  92. if (obj == null)
  93. return false;
  94. if (getClass() != obj.getClass())
  95. return false;
  96. Employee other = (Employee) obj;
  97. if (empId != other.empId)
  98. return false;
  99. if (name == null) {
  100. if (other.name != null)
  101. return false;
  102. } else if (!name.equals(other.name))
  103. return false;
  104. if (Float.floatToIntBits(salary) != Float.floatToIntBits(other.salary))
  105. return false;
  106. return true;
  107. }

  108. /**
  109. * 覆盖toString方法,将职工对像的姓名,工号,工资进行输出;
  110. */
  111. @Override
  112. public String toString() {
  113. return "姓名:" + name + " 工号:" + empId + " 工资" + salary;
  114. }

  115. @Override
  116. /**
  117. * 按工号排序,一般工号是不可能相同的;因此不考虑工号相同,也就没必要比较其他的,
  118. * 使用int型的包装类Integer,他自身有compareTo方法;这样更优雅,免得自己写出错;
  119. */
  120. public int compareTo(Employee o) {
  121. return new Integer(this.empId).compareTo(new Integer(o.empId));
  122. }
  123. }

  124. /**
  125. * 继承Employee类
  126. *
  127. * @author 荣强 由于是按工号排序的,而且工号不可能相同,因此不用实现Comparable接口;
  128. */
  129. class Manager extends Employee {
  130. private float bonus;

  131. public float getBonus() {
  132. return bonus;
  133. }

  134. public void setBonus(float bonus) {
  135. this.bonus = bonus;
  136. }

  137. public Manager() {
  138. super();
  139. }

  140. @Override
  141. public String toString() {
  142. // 使用父类的方法,加上子类的特有属性;
  143. return super.toString() + " 奖金:" + bonus;
  144. }
  145. }
复制代码
结果:

XKP$D2]@8QW1R9ZID4MLY]M.jpg (27.41 KB, 下载次数: 0)

结果

结果
回复 使用道具 举报
请注意:第29行注释和第三个输出结果;
也就是说,设置的时候没有设置奖金这个方法,但是输出的时候确实是有奖金这个属性。。。
确实有点难以解释。。。
回复 使用道具 举报
高手在民间啊,前来凑热闹{:soso_e100:}
回复 使用道具 举报
wuddd 高级黑马 2013-5-10 14:02:13
17#
本帖最后由 吴超老师 于 2013-5-10 14:05 编辑
Miss小强 发表于 2013-5-10 11:11
突然想到我入学测试题也有一个类似的问题,不多说,上代码:结果:

我没有仔细看清代码,呵呵
回复 使用道具 举报
wuddd 高级黑马 2013-5-10 14:04:42
18#
Miss小强 发表于 2013-5-10 10:56
java编译和运行的基本单位是类,必须放在一个类里面。
这个我知道,但是前面那句,第二种,第三种无法单独 ...

sorry,我看错了,没有注意到都在一个Person类中。

就当愚人节乐一乐吧。

我收回刚才的观点啊。换一个观点,选第三种!
回复 使用道具 举报
吴超老师 发表于 2013-5-10 14:04
sorry,我看错了,没有注意到都在一个Person类中。

就当愚人节乐一乐吧。

嗯嗯,无论如何还是得感谢老师啊。。。咱云四见。。。
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马