• 课后作业


    1、使用类的静态字段和构造函数,我们可以跟踪某个类所创建对象的个数。请写一个类,在任何时候都可以向它查询“你已经创建了多少个对象?”。

    设计思路:定义类的构造函数时使静态变量i进行i++,即每构造一次就叠加一个构造的对象数。

    程序流程图:

       

    源程序代码:

     1 package tiaoshi;
     2 import java.util.Scanner;
     3 public class Tiaoshi 
     4 {
     5     static int i=0;
     6     public Tiaoshi()
     7     {
     8         i++;
     9     }
    10     public static int getTimes()
    11     {
    12         return i;
    13     }
    14     public static void main(String[] args) 
    15     {
    16         int x=1;
    17         Scanner con=new Scanner(System.in);
    18         for(;x!=0;)
    19         {
    20             System.out.print("构建个数(0退出):");
    21             x=con.nextInt();
    22             for(int t=0;t<x;t++)
    23             {
    24                 Tiaoshi g=new Tiaoshi();
    25             }    
    26             System.out.println("程序已经创建对象的个数为:"+getTimes());
    27         }
    28     }
    29 }

    结果截图:

       

    2、验证ClassAndObjectTest.java(使用自定义类)

     1 public class ClassAndObjectTest
     2 {
     3     public static void main(String[] args)
     4     {
     5         //创建类的实例,定义一个对象变量引用这一实例
     6         MyClass obj = new MyClass();
     7         //通过对象变量调用类的公有方法
     8         obj.myMethod("Hello");
     9         //给属性赋值
    10         obj.setValue(100);
    11         //输出属性的当前值
    12         System.out.println(obj.getValue());
    13         //直接访问对象公有字段
    14         obj.Information = "Information";
    15         //输出对象公有字段的当前值
    16         System.out.println(obj.Information);
    17     }
    18 }
    19 class MyClass
    20 {
    21     public String Information = "";
    22     public void myMethod(String argu)
    23     {
    24         System.out.println(argu);
    25     }
    26     private int value;
    27     public int getValue()
    28     {
    29         return value;
    30     }
    31     public void setValue(int value)
    32     {
    33         this.value = value;
    34     }
    35 }

    验证结果:

       

    3、早期我们经常这样定义变量“int value=100;”,而前面的示例中这样定义变量“MyClass obj=new MyClass();”,这两种方式定义的变量是一样的吗?

      这两种变量是不一样

      前者原始数据类型,int,float之类的变量当声明一个原始数据类型的变量时,实际上并没有创建一个对象,此变量=null

      后者引用类型变量,“引用”一个对象的变量称为“引用类型”的变量定义一个原始类型的变量时,会马上给其分配内存而对象变量的初始化中,该变量若不引用一个真实的对象,则必须声明为null。而且引用对象后的对象变量,且如果不再使用此变量,会回收类定义的对象所占用的内存。

    4、对于原始数据类型的变量(比如int),可以直接使用“==”判断两变量值是否相等,那么对象变量也可以使用“==”判断两变量值是否相等吗?

      不可以,类似于字符串的比较大小,使用equals()进行比较,用法与其相同。当“==”施加于“原始数据类型”变量时,是比较变量所保存的数据是否相等“==”施加于“引用类型”变量时,是比较这两个变量是否引用同一对象。引用代表地址,所以“==”实际上相当于比较两个引用类型变量中保存的对象地址是否相同

    5、请输入并运行以下代码,得到什么结果?

     1 public class Test
     2 {
     3     public static void main(String[] args)
     4     {
     5         Foo obj1 = new Foo();
     6         Foo obj2 = new Foo();
     7         System.out.println(obj1==obj2);
     8     }
     9 } 
    10 class Foo
    11 { 
    12     int value=100;
    13 }

    结果截图:

       

    6、如何比较两个对象的“内容”是否一样?

      “内容相等”,其实是就“对应字段值”一致。

      在JAVA中要比对两个对象的字段值,可以 重写基类的equals()方法;Object是Java的最顶层基类,其中定义了equals( )方法。

      重写基类的equals()方法:

     1 public class ObjectEquals
     2 {
     3     public static void main(String[] args)
     4     {
     5         MyTestClass obj1=new MyTestClass(100);
     6         MyTestClass obj2=new MyTestClass(100);
     7         System.out.println(obj1==obj2);
     8         System.out.println(obj1.equals(obj2));
     9     }
    10 }
    11 class MyTestClass
    12 {
    13     public int Value;
    14      public boolean equals(Object obj)
    15      {
    16           return ((MyTestClass)obj).Value==this.Value;
    17      }
    18     public MyTestClass(int initValue)
    19     {      
    20         Value=initValue;
    21     }
    22 }

    结果截图:

       

    7、以下代码为何无法通过编译?哪儿出错了?

     1 public class Test
     2 {
     3     public static void main(String[] args)
     4     {
     5          Foo obj1 = new Foo();
     6     }
     7 }
     8 class Foo
     9 {
    10     int value;
    11     public Foo(int initValue)
    12     {
    13         value=initValue;
    14     }
    15 }

      结论:如果类提供了一个自定义的构造方法,将导致系统不再提供默认构造方法。所以“Foo obj1 = new Foo();”中需要添加默认的参数。

    8、如果一个类中既有初始化块,又有构造方法,同时还设定了字段的初始值,谁说了算?

     1 package tiaoshi;
     2 public class Tiaoshi
     3 {
     4     public static void main(String[] args)
     5     {
     6         tiao obj=new tiao();
     7         System.out.println(obj.field);
     8         obj=new tiao(300);
     9         System.out.println(obj.field);
    10     }
    11 }
    12 class tiao
    13 {
    14     {
    15          field=200;
    16     }
    17     public int field=100;
    18     public tiao(int value)
    19     {
    20          this.field=value;
    21     }
    22     public tiao()
    23    {
    24 
    25     }
    26 }

      在“public int field = 100;”在“{field=200;}”之前时,是“{field=200;}”说了算;在之后时,是“public int field = 100;”说了算。也就是谁比较靠后就是谁初始化起作用。执行类成员定义时指定的默认值或类的初始化块,到底执行哪一个要看哪一个“排在前面”。

      构造函数,类的初始化块不接收任何的参数,只要一创建类的对象,它们就会被执行。因此,适合于封装那些“对象创建时必须执行的代码”。

      运行结果:

      ①“public int field = 100;”在“{field=200;}”之前:

       

      ②“public int field = 100;”在“{field=200;}”之后:

       

    9、请运行TestStaticInitializeBlock.java示例,观察输出结果,总结出“静态初始化块的执行顺序”。

     1 class Root
     2 {
     3     static
     4     {
     5         System.out.println("Root的静态初始化块");
     6     }
     7     {
     8         System.out.println("Root的普通初始化块");
     9     }
    10     public Root()
    11     {
    12         System.out.println("Root的无参数的构造器");
    13     }
    14 }
    15 class Mid extends Root
    16 {
    17     static
    18     {
    19         System.out.println("Mid的静态初始化块");
    20     }
    21     {
    22         System.out.println("Mid的普通初始化块");
    23     }
    24     public Mid()
    25     {
    26         System.out.println("Mid的无参数的构造器");
    27     }
    28     public Mid(String msg)
    29     {
    30         this();
    31         System.out.println("Mid的带参数构造器,其参数值:" + msg);
    32     }
    33 }
    34 class Leaf extends Mid
    35 {
    36     static
    37     {
    38         System.out.println("Leaf的静态初始化块");
    39     }
    40     {
    41         System.out.println("Leaf的普通初始化块");
    42     }    
    43     public Leaf()
    44     {
    45         super("Java初始化顺序演示");
    46         System.out.println("执行Leaf的构造器");
    47     }
    48 }
    49 public class TestStaticInitializeBlock
    50 {
    51     public static void main(String[] args)
    52     {
    53         new Leaf();
    54     }
    55 }

    结果截图:

       

    10、静态方法中只允许访问静态数据,那么,如何在静态方法中访问类的实例成员(即没有附加static关键字的字段或方法)?

     1 public class text4
     2 {
     3      public static void main(String[] args)
     4     {
     5           System.out.println("(静态变量)total_employees =  "+Employee.clear());
     6           Employee e = new Employee();
     7           System.out.print("(实例变量)name =  "+e.name);
     8     }
     9 }
    10 class Employee
    11 {
    12      String name = "2";
    13      static int total_employees = 0;
    14      static int clear()
    15     {
    16          return total_employees;
    17      }
    18      static void clear2()
    19     {
    20 
    21     }
    22 }

    结果截图:

       

    11、 两对整数明明完全一样,为何一个输出true,一个输出false?

    1  public static voidmain(String[] args)
    2 {
    3     Integer i1=100;
    4     Integer j1=100;
    5     System.out.println(i1=j1);
    6     Integer i2=129;
    7     Integer j2=129;
    8     System.out.println(i2=j2);
    9 }

      通过valueOf方法创建Integer对象的时候,如果数值在[-128,127]之间,将返回指向IntegerCache.cache中已经存在的对象的引用;否则创建一个新的Integer对象。i1和i2的数值为100,所以会直接从cache中取已经存在的对象,所以i1和j1指向的是同一个对象,而i2和j2则是分别指向不同的对象。

  • 相关阅读:
    django学习第85天Django的Ajax
    django学习第84天Django常用字段和参数
    django学习第83天Django聚合查询.分组查询.FQ查询
    django学习第82天Django多表查询
    django学习第81天Django模板层2(单表查询.模块的导入和继承.静态文件配置)
    django学习第80天Django模板层1
    django学习第79天Django视图层
    Linux 内核文档翻译
    Linux设备模型——设备驱动模型和sysfs文件系统解读
    内核空间内存申请函数kmalloc kzalloc vmalloc的区别
  • 原文地址:https://www.cnblogs.com/guobin-/p/7687607.html
Copyright © 2020-2023  润新知