类与对象的关系:
类就是对现实生活的描述,定义类就是在描述事物,就是在定义属性(变量)和行为(函数).
属性和行为共同成为类中的成员.
对象:就是这类事物,实实存在的个体.
举例:
class Car { //描述颜色 String color="red"; //描述轮胎 int number=4; //汽车发动 void run() { System.out.println(color+","+number); } } class CarDemo { public static void main(String[] args) { //生产汽车.在java中通过new操作符来完成 //其实就是在堆内存产生一个实体 new Car();//产生一个汽车对象,对象里面具备了颜色和轮胎数 Car c= new Car();//c为 类 类型变量(引用型变量) //类类型的变量指向该类所产生的对象.(在内存中如下图) c.run();} }Car c=new Car( );在内存中:成员变量和局部变量:
①作用范围:
成员变量作用于整个类中.
局部变量作用于函数中,或者语句(for循环)中.
②在内存中的位置成员变量:在堆内存中,因为对象的存在,才在内存中存在
局部变量:存在栈内存中.
匿名对象:
举例:
new Car( ).number=5;//执行完之后变成 垃圾 因为没有任何引用
new Car( ).color="blue”;//执行完之后变成垃圾
new Car( ).run( );//run( )是一个方法,里面有运行内容,比较有意义
注意:这是三个不同对象
内存图:
因此:
①当对 对象的方法 只调用一次时,可以用匿名对象来完成.
class Car { //描述颜色 String color; //描述轮胎 int number; //汽车发动 void run() { System.out.println(color+","+number); } } //对上面的CarDemo改变下 class CarDemo_2 { public static void main(String[] args) { Car q=new Car(); show(q); //show(new Car());//采用匿名对象作为实参传递 } public static void show(Car c) { c.number=3 c.color="black"; c.run(); } }Car q=new Car();show(q);在内存中大致情况:show(new Car());//跟上面的new Car( )不是一个对象
内存大致情况:
②因此 匿名对象可以做为 实际参数 传递.
构造函数:
①函数名与类名相同
②不用定义返回值类型
③不可以写return语句
作用:可以用于初始化对象
注意:当一个类中没有定义构造函数时,那么系统会默认给该类加入一个空参数的构造函数(类名 ( ) { })
当类中自定义了构造函数后,默认的构造函数就没有了
构造函数和一般函数主要区别:
①构造函数是在对象一建立就运行,给对象初始化.
而一般方法是对象调用才执行
②一个对象建立,构造函数只运行一次.
而一般方法可以被该对象调用多次.
什么时候定义构造函数?
当分析事物(对象)时,该事物存在具备一些 特性 或者 行为,那么将这些内容定义在构造函数中
构造代码块:
class Person { int age; String name; Person() { System.out.println("name="+name+",age="+age);//打印默认值 } Person(String n)//构造函数重载 { name=n; } public void cry() { System.out.println("wawawa..."); } /* 构造代码块:给对象进行初始化,对象一建立就运行 而且优先于构造函数执行
因此,构造代码块可以访问该对象的成员. 与构造函数的区别: ①构造代码块给所有的对象初始化 ②构造函数给对应的对象初始化 ③构造代码块中定义的是不同对象共性的初始化内容 */{ cry(); } } class ConstructF { public static void main(String[] args) { Person p= new Person(); Person p2= new Person("zhangsan"); } }
this关键字:
//成员函数中 局部变量 与 类中的成员变量 重名 class Person { private int age; private String name; Person() { System.out.println("name="+name+",age="+age);//打印默认值 } /* 注意:"="前面的name也是局部变量name,而不是成员变量 name,当局部中有(name),就在局部中找来使用. 如果局部没有,则找成员(name) 使用 */ Person(String name) { this.name=name;//解决方法:this.name=name; //相当于p.name=name System.out.println(this); } void speak() { System.out.println("name="+name+",age="+age);//省略了this.name,this.age show();//show()被对象调用,前面省略了this.show();类中的成员之间互相调用,通过对象完成的. System.out.println(this); } void show() { System.out.println("name="+name); } } class Construct_2 { public static void main(String[] args) { Person p=new Person("zhangsan"); System.out.println(p); Person p2=new Person("lisi"); System.out.println(p2); //p.speak(); } } /* 总结: this 就是 所在(这个)函数 所属对象 的 引用变量 上例:所在函数:Person(String name){} 所属对象:new Person("zhangsan"); this指向对象new Person("zhangsan") 也就是this和p指向同一个对象 简单理解为:哪个对象调用this所在的函数,this就指向哪个对象 */
前两个哈希地址(p,对应的this)相同,后两个哈希地址(p2,对应的this)相同,this是引用变量依然在
栈内存中.
this应用:当定义类中函数时,该函数内部要用到 调用该函数的 对象 时,这时用this来表示这个对象,
但凡本类函数 内部使用到本类对象,都用this表示.例如:
//简单比较两个人年龄是否相同
class People { private int age; private String name; People(String name,int age) { this.name=name; this.age=age; } public boolean compare(People p)//判断两个人的年龄是否相等 { return this.age==p.age; } } class ThisTest { public static void main(String[] args) { People p=new People("zhangsan",10); People q=new People("lisi",20); System.out.println(p.compare(q)); } }最后一点:this语句构造函数之间的调用只能用this语句示例:class Person { private int age; private String name; Person() { System.out.println("Person() is called"); } Person(String name) { this();//而这个this语句会调用Person()构造函数 this.name=name; System.out.println("Person(String name) is called"); } Person(String name,int age) { //this.name=name; this(name);//相当于对this(p)指向的对象中的name初始化 //那么会调用Person(String name)构造函数 this.age=age; } } class Construct_2 { public static void main(String[] args) { Person p=new Person("lisi",20); } }
注:
this语句只能定义在构造函数的 第一行
this语句不允许在 一般函数 中使用,只能在 构造函数 间
一般用在当内部有多个构造函数时,只想对外提供一些,其它的(private)构造函数只允许类的内部调用.
不允许构造函数之间进行相互调用如:
Person( )
{
this(name);
}
Person(String name)
{
this( );
}
构成死循环.