类和对象
一、使用类的静态字段和构造函数,我们可以跟踪某个类所创建对象的个数。请写一个类,在任何时候都可以向它查询“你已经创建了多少个对象?”。
1.
(1)源代码
//在静态中访问类的实例变量,在静态方法中,先生成一个对象,用对象成员访问实例成员
public class ButtonFactory {
public static void main(String args[])
{
FF a=new FF();FF b=new FF();FF c=new FF();
}
static class FF
{
int n;
FF()
{
System.out.println("你已经创建了对象");
}
}
}
(2)设计思想
在类中定义一个构造函数,函数体中写上一句话用来显示,通过输出的话的个数,显示创建了多少对象。每一次new一个后都会调用构造函数,就会有一句话输出,从而实现查询创建了多少对象的目的。
(3)程序结果截图
二、验证课件上的代码,并将所有的动手动脑或要求
1.运行代码,得实验结果(验证“==”)
(1)源代码
public class Test {
public static void main(String args[])
{
Foo obj1=new Foo();
Foo obj2=new Foo();
System.out.println(obj1==obj2);
}
}
class Foo{
int value=100;
}
(2)程序结果截图
(3)结果分析结论
当“==”施加于原始数据类型变量时,是比较变量所保存的数据是否相等
当“==”施加于引用类型变量时,是比较这两个变量是否引用同一对象。包括数据和地址,引用代表地址,所以“==”实际上相当于比较两个引用类型变量中保存的对象地址是否相同;用equals可以比较两个引用类型变量的内容。
2.构造方法
当创建一个对象时,它的构造方法会被自动调用。构造方法与类名相同,没有返回值。
如果类没有定义构造函数,Java编译器在编译时会自动给它提供一个没有参数的“默认构造方法”
这个图片中的就用错了,当类中给了一个自定义的构造方法,就会导致系统不再提供一个默认的构造方法。同一个类中可以有多个构造函数,多个构造函数之间通过参数来区分,这也是方法的重载,构造函数之间可以相互调用。
public class MyTextClass {
public static void main(String args[])
{
MyTextClass1 obj=new MyTextClass1();
/*MyTextClass1 aa =aa.MyTextClass1();
System.out.println(aa.Value);*/
System.out.println(obj.Value);
obj=new MyTextClass1(100);
System.out.println(obj.Value);
}
}
class MyTextClass1
{
{
Value=200;
}
public int Value=100;
/* public boolean equals(MyTextClass1 a)
{
return a.Value==this.Value;
}*/
public MyTextClass1 (int initV)
{
Value=initV;
}
public MyTextClass1()
{
}
}
根据结果可以发现,如果一个类中既有初始化块,又有构造方法,同时还设定了字段的初始值,构造方法说了算。
3.静态初始化的执行顺序
(1)源程序
class Root
{
static{
System.out.println("Root的静态初始化块");
}
{
System.out.println("Root的普通初始化块");
}
public Root()
{
System.out.println("Root的无参数的构造器");
}
}
class Mid extends Root
{
static{
System.out.println("Mid的静态初始化块");
}
{
System.out.println("Mid的普通初始化块");
}
public Mid()
{
System.out.println("Mid的无参数的构造器");
}
public Mid(String msg)
{
//通过this调用同一类中重载的构造器
this();
System.out.println("Mid的带参数构造器,其参数值:" + msg);
}
}
class Leaf extends Mid
{
static{
System.out.println("Leaf的静态初始化块");
}
{
System.out.println("Leaf的普通初始化块");
}
public Leaf()
{
//通过super调用父类中有一个字符串参数的构造器
super("Java初始化顺序演示");
System.out.println("执行Leaf的构造器");
}
}
public class TestStaticInitializeBlock
{
public static void main(String[] args)
{
new Leaf();
}
}
(2)截图:
(3)分析
静态初始化块只执行一次。
创建子类型的对象时,也会导致父类型的静态初始化块的执行。类的静态方法只能访问类的静态成员
4. 静态方法中只允许访问静态数据,那么,如何在静态方法中访问类的实例成员(即没有附加static关键字的字段或方法)?
(1)解决方法:
在静态中访问类的实例变量,在静态方法中,先生成一个对象,用对象成员访问实例成员,StaticDemo obj=new StaticDemo()
(2)源代码
//在静态中访问类的实例变量,在静态方法中,先生成一个对象,用对象成员访问实例成员
public class ButtonFactory {
public static void main(String args[])
{
}
static class FF
{
String name;
static void clear()
{
FF f=new FF();//先定义一个对象
f.name="string";//用对象去访问实例成员
}
}
}
5. 两对整数明明完全一样,为何一个输出true,一个输出false
(1)源代码
public class StrangeIntegerBehavior
{
public static void main(String[] args)
{
Integer i2=129;
Integer j2=129;
System.out.println(i2==j2);
Integer i1=100;
Integer j1=100;
System.out.println(i1==j1);
}
}
(2)分析结果
首先先比较i和j是否一样,地址是否相同。它会调用interger.valueOf(i),就比较i是不是i》=128||i《=-128,129就会返回一个新的数,不一样了,所以false,100不在范围内就不会返回新值了,还是一样的,所以true。
(3)截图