黑马程序员技术交流社区

标题: 代码写法。。迷惑 [打印本页]

作者: 刘 佳    时间: 2012-10-16 10:27
标题: 代码写法。。迷惑
本帖最后由 刘 佳 于 2012-10-16 15:32 编辑

问下各位 ,红色那句加不加编译都成功,那正规点写法是加还是不加呢,加不加有何区别,我有点迷糊,求解释。

class MethodString
{
        
        public static void main(String[] args)
        {

                String s1="    abcd  efg  ";
                TrimDemo t=new TrimDemo();
                System.out.println(t.trim(s1));
               
        }
}

class TrimDemo
{
        //private String s1;
        public String trim(String s1)
        {
                int pos=0;
                int x=s1.length()-1;
                while (s1.charAt(pos)==' ')        
                        pos++;
                while(s1.charAt(x)==' ')
                        x--;
                return s1.substring(pos,x+1);
        }
}


作者: 梁世喜    时间: 2012-10-16 10:49
比如说生产车间生产产品。
这个过程需要材料  s1  (也i就是参数)
车间本身只是按照流程 用材料(其他地方拿来的)生产产品
像函数    public String trim(String s1)   s1是材料(形式参数标明这里需要String 类型的材料),是通过加工 s1 来返回 String
这里是谁调用谁提供参数。所以一般不写//private String s1;

当然主要根据需要进行编码,
看如下
  1. private String str;

  2. //此方法操作的是参数str
  3. public String method(String str)
  4. {
  5.       return str.substring(index);
  6. }
  7. //以下方法操作的是自身属性 private String str;
  8. public String method()
  9. {
  10.       return str.substring(index);
  11. }
复制代码

作者: 舒远    时间: 2012-10-16 13:29
本帖最后由 舒远 于 2012-10-16 15:29 编辑

加上了红色的代码说明你这个类需要s1这个属性,这个加不加需要看你的需求,s1到底是否属于当前类的属性?
考虑这个问题的过程就是面向对象设计的过程。

如果加上,就要考虑trim方法操作的是不是属性s1,如果是,trim方法则应该修改,修改成改变s1值的方式,目前你的代码都是改变的参数s1,跟属性没有任何关系。
如果不加,则trim最好设置成static的,因为trim方法的执行过程跟类的对象没有关系,也不涉及操作对象属性的过程。作为工具来使用则较好。
综上,类可以有如下两种基本的改法:
//修改属性s1的方式
class TrimDemo
{
        private String s1;
        public String trim()
        {
                int pos=0;
                int x=this.s1.length()-1;
                while (this.s1.charAt(pos)==' ')        
                        pos++;
                while(this.s1.charAt(x)==' ')
                        x--;
                this.s1 = this.s1.substring(pos,x+1);
                return this.s1;
       }
}

//作为工具类的实现
class TrimDemo
{
        public static String trim(String s1)
        {
                int pos=0;
                int x=s1.length()-1;
                while (s1.charAt(pos)==' ')        
                        pos++;
                while(s1.charAt(x)==' ')
                        x--;
                return s1.substring(pos,x+1);
        }
}


作者: 陈虹旭    时间: 2012-10-16 14:24
class TrimDemo
{
        //private String s1;这句不加上当然可以成功的,因为你的TrimDemo类中定义的是一个方法,这个方法要求传入一个String类型的参数,在调用时候只要保证传入的参数是String类型的就可以了,而定义String类型的数据操作就没有必要一定要在本类中完成了。说白了就是你的方法并没有用到你的这个s1常量        
        public String trim(String s1)
        {
                int pos=0;
                int x=s1.length()-1;
                while (s1.charAt(pos)==' ')        
                        pos++;
                while(s1.charAt(x)==' ')
                        x--;
                return s1.substring(pos,x+1);
        }
}



作者: 黄佳    时间: 2012-10-16 14:26
    //private String s1;   这里的 s1 是成员变量

     public String trim(String s1)    这里的 s1 是形式参数(其参数名可以任意取)   只不过形式参数的名字与成员变量的名字重名

    String s1="    abcd  efg  ";  这里的 s1 是main方法里的局部变量  

     System.out.println(t.trim(s1));  这里传的参数 s1 是传递的main方法里的局部变量 s1   如果main方法里没有局部变量 s1 则再看 t 对象有没有s1变量 有则传递,没有则会报错
作者: 宋旭珂    时间: 2012-10-16 15:04
private String s1;//这样会在内存中单独开辟一块空间来存储s1变量,并赋初值为null,有效范围为整个类
public String trim(String s1){}//在此定义的s1变量只在该函数内有效
以上方式定义了两次String变量,第一次定义的用不到,反而在内存中多开辟了一块空间,每当调用所在的类时就多开辟内存空间,不太好。建议只在定义函数时在函数参数内定义变量,这样只供函数使用的局部变量定义在函数内部,这样可能较好。

作者: 徐帅    时间: 2012-10-16 16:51
这个问题,本人曾经在程序中遇到过,并且抛出了NullPointerException
主要问题是:
在泛型的练习中,继承的时候,如果加上了这句话,并且在子类中复写了父类中的,getName方法那么
在执行的时候,使用了子类的getName方法,但是在进行比较的时候却使用了父类的方法,也就是说使用了父类
的name,由于子类没有使用父类的方法去初始化name,也就是说这两个name,不是同一个,父类中的name = null。
所以在比较的时候出现了NullPointerException,
但是如果子类中没有定义自己的 name属性,编译器就会报错

当然这样的问题出现的概率还是比较小,这是由于个人的粗心发现的问题,个人的总结是:

1.在继承中,如果子类在继承父类的时候从父类获取的方法,没有特殊功能或扩展时,就不要复写,
当然大多数是自己粗心,或者copy代码的时候造成的,本人就是。
2.父类已经定义的属性,子类就不要再定义了,纯属多余

个人发现的小问题,希望对楼主有所帮助
  1. import java.util.Comparator;
  2. import java.util.Iterator;
  3. import java.util.TreeSet;

  4. class Person5 {
  5.         private String name;

  6.         Person5(String name) {
  7.                 this.name = name;
  8.         }

  9.         public String getName() {
  10.                 return name;
  11.         }
  12. }

  13. class Student5 extends Person5 implements Comparable<Person5>// <? super
  14.                                                                                                                                 // E>接收E及E的父类型,这里的E指Student
  15. {
  16.         private String name;

  17.         Student5(String name) {
  18.                 super(name);
  19.         }

  20. //返回的是子类的name,而初始化的是父类的name;
  21. //切记:没有实现特别需求时不用覆盖
  22.         /*public String getName(){
  23.                 Return name;
  24. }
  25. */
  26.         public int compareTo(Person5 s) {
  27.                 return this.getName().compareTo(s.getName());

  28.         }
  29. }

  30. // 因为是继承关系,所以子类有父类的方法,如果类型定义为父类,
  31. // 那么使用的是父类方法,所以可以传入父类,一般也应该定义为父类
  32. //那么整个继承体系都可以使用该比较器,提高了扩展性

  33. class Comp implements Comparator<Person5> // <? super E>接收E及E的父类型,这里的E指所传入的继承体系中的子类型
  34. {
  35.         public int compare(Person5 p1, Person5 p2) {
  36.                 // Person s1 = new Student("abc1");
  37.                 return p1.getName().compareTo(p2.getName());
  38.         }
  39. }


  40. class GeneticDemo {
  41.         public static void main(String[] args) {

  42.                 TreeSet<Student5> ts = new TreeSet<Student5>(new Comp());

  43.                 ts.add(new Student5("abc1"));
  44.                 ts.add(new Student5("abc8"));
  45.                 ts.add(new Student5("abc5"));
  46.                 ts.add(new Student5("abc3"));

  47.                 Iterator<Student5> it = ts.iterator();
  48.                 while (it.hasNext()) {

  49.                         System.out.println(it.next().getName());
  50.                 }
  51.         }
  52. }
复制代码





欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2