黑马程序员技术交流社区

标题: final 小疑惑?求助 [打印本页]

作者: 黑马17期-闫东东    时间: 2013-3-12 21:32
标题: final 小疑惑?求助
final 可以修饰属性:代表这个属性是常量。       方法:不可以被重写;            类:不可以被继承
class Demo4
{
        final int id;  //实例属性

        Demo4(int id){
                this.id=id;
        }

        public static void main(String[] args)
        {
                Demo4 d=new Demo4(100);
               
                                 Demo4 dd=new Demo4(10);
                System.out.println(d.id);//打印 100
                System.out.println(dd.id);//打印 10
        }
}
是不是如果当前变量是用final修饰的,并且没有初始化值,那么我们可以在构造方法中,对其进行赋值操作?

class Demo
{
        public static void main(String[] args)
        {
                Son son=new Son();

                son.show();
        }
}

/*
//不可以被继承
final class Father
{
}
*/

class Father
{
             final void show(){
        System.out.println("father show");
       
        }
}

class Son extends Father
{
               

}

//打印  father show
从打印结果看:final方法不可以被重写,但是可以被子类继承.



作者: 徐鸿燕    时间: 2013-3-12 21:45
你的打印结果已经解决你的疑惑所在。- -
作者: 刘国涛    时间: 2013-3-12 21:53
被final修饰的变量是一个常量,只能被赋值一次,但是你new了两个对象就有两个id值,但其中任意一个不能再被赋值。
class Demo4
{
         final int id;

        Demo4(int id){
                 this.id=id;
         }

        public static void main(String[] args)
        {
                 Demo4 d=new Demo4(100);//一个对象

                 d.id=99;//无法为最终变量id分配值
                 Demo4 dd=new Demo4(10);//另一个对象
                 System.out.println(d.id);
                 System.out.println(dd.id);
         }
}
作者: 我自信我很牛    时间: 2013-3-12 22:25
final  这个关键字其实我们可以从字面去理解,是最后一个,所以修饰变量后,变量不再是变量,我们可以记忆为最后一次变,所以只能被赋值一次,
修饰方法后也就是说这个方法也是最后一个,所以不能附加功能,就不能重写了,
修饰类后,这个类就是最后一个,所以没有后代了,所以不能被赋值;
总结:很多关键字我们都能总结出类似的理解,从字面去理解记忆,这样以后使用也不会混乱。切记不要记那些代码规律,那样使用起来也不确定该不该加了就乱了。
以上是个人学习体会,仅个人意见,供参考
作者: 孙晋学    时间: 2013-3-12 22:27
finale修饰的成员变量必须被显式的初始化,且只能赋值一次。显式初始化有两种方式:定义成员变量是直接赋值或者通过构造方法赋值
  1. class Demo{
  2.     final int id = 4;
  3. }
  4. 或者
  5. class Demo{
  6.    final int id;
  7.    Demo(int id){
  8.        this.id = id;
  9.    }
  10. }
复制代码
下面的代码是不合法的:
  1. class Demo{
  2.     final int id = 4;
  3.     Demo(int id){
  4.       this.id = id;//编译错误,只能赋值一次
  5.     }
  6. }
复制代码
Demo4 d=new Demo4(100);   Demo4 dd=new Demo4(10);创建了两个对象,有两个不同的 final int id
作者: 樊玲    时间: 2013-3-12 22:32

final 可以修饰属性:代表这个属性是常量。       方法:不可以被重写;            类:不可以被继承
class Demo4
{
        final int id;  //实例属性           ***这里id 被final修饰后,可以在构造函数中进行一次赋值,也是唯一一次。

        Demo4(int id){                        //*** 构造函数,在执行Demo4 d=new Demo4(100); 时,把 100 给了 this.id  即id 为100
                this.id=id;
        }

        public static void main(String[] args)
        {
                Demo4 d=new Demo4(100);            //***   这里对象一建立,构造函数便对其进行了实例化,实例成员属性 即id变为了100
                                                                                           
                 Demo4 dd=new Demo4(10);     //*** 我们知道这里被final 修饰的成员属性如果被一次赋值,可以被看作是一个常量100。
                                                                                     //***  所以说再new一个对象的时候,传入的id的值10是不能被赋值的。常量怎么能再被赋值呢? 对吧,你可以这么理解。。
                System.out.println(d.id);//打印 100
                System.out.println(dd.id);//打印 10
        }
}
是不是如果当前变量是用final修饰的,并且没有初始化值,那么我们可以在构造方法中,对其进行赋值操作?

class Demo
{
        public static void main(String[] args)
        {
                Son son=new Son();

                son.show();
        }
}

/*
//不可以被继承
final class Father
{
}
*/

class Father
{
             final void show(){
        System.out.println("father show");
        
        }
}

class Son extends Father
{
               

}
注:被final修饰的属性可以看作是一个常量(也可以在构造函数中进行一次赋值),被final修饰的方法,不可以被重写,被final修饰的类不可以被继承。
  希望对楼主有用~~~
作者: 王龙涛    时间: 2013-3-12 22:44
由于在java的语法中,声明和初始化是联系在一起的,
也就是说:如果你不显示的初始化一个变量,系统会自动用一个默认值来对其进行初始化。(如int就是0)
对于final变量,在声明时,如果你没有赋值,系统默认这是一个空白域,在构造函数进行初始化,
如果是静态的,则可以在初始化块。
作者: 聂斌    时间: 2013-3-13 01:24
本帖最后由 聂斌 于 2013-3-13 01:28 编辑

呵呵同学:

1..是不是如果当前变量是用final修饰的,并且没有初始化值,那么我们可以在构造方法中,对其进行赋值操作?

对象一建立就会调用与之对应的构造函数。

构造函数的作用:可以用于给对象进行初始化。也就是说当我们在堆内存中产生对象的时候这个对象他需要一个初始化动作,,就是当你创建对象时,,这个对象会做初始化动作给对象里的属性初始化,,

注意:
final 标记的成员变量必须在声明的同时赋值,如果在声明的时候没有赋值,那么只有
一次赋值的机会,而且只能在构造方法中显式赋值,然后才能使用。
lfinal标记的局部变量可以只声明不赋值,然后再进行一次性的赋值。

id是类中的成员,,所以构造函数也会给他初始化的,,如果你没有显示的指定id的值的话,,那么系统会给id加个默认的值0,,,在这里你通过构造函数给id赋值是合理的,,当id没有被final修饰时他是个变量你可以给id赋值多次,,但是flnal修饰后这个id就是常量了,,意思是id只能被赋值一次,,,,,因为被final修饰的变量是一个常量只能赋值一次,,,

看下面代码就能明白为什么常量只能赋值一次,,,,

final int id;  //实例属性

      Demo4(int id){
              this.id=id;
      }

      public static void main(String[] args)
      {
              Demo4 d=new Demo4(100);
              d.id=6;          //(a)   报错
              
      }

发现(a) 处的 id 编译错误,,,,因为你构造函数new Demo4(10);对id赋值一次后那个id就不能被第二次赋值了,,因为id是常量,只能被赋值一次,,,


第二个问题:final方法不可以被重写,但是可以被子类继承.  

final方法 :
如果一个类不允许其子类覆盖某个方法,则可以把这个方法声明为final方法。

使用final方法的原因:
把方法锁定,防止任何继承类修改它的意义和实现。

我是这样理解的..那个show()方法他也是类中的成员,,只是他被final修饰了,,就是说这个方法定义好了之后就不能被改变了,,就好比上面的变量被final修饰后,那个变量只能被赋值一次,,,同理方法也一样的,,,区别是你上面的变量没有被你显示的初始化,,而final修饰的方法是你自己已经定义好的了,,那么这个方法被定义好之后就不能被修改了,,也就是子类不能覆盖这个方法,,同时子类具备父类的成员,,当子类继承父类的同时,子类也拿到了父类中的show方法,,只是子类不能对这个show方法做修改...



















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