类与对象

类与对象的基本概念

类:是抽象的概念集合,表示的是一个共性的产物,类中定义的是属性和行为(方法);(不能用)

对象:对象是一种个性的表示,表示一个独立的个体,每个对象拥有自己独立的属性,依靠属性来区分不同的对象。(能用)

区别:类是对象的模板,对象是类的实例,类是通过对象才可以使用的,而在开发之中应该先产生类,之后再产生对象。

注意: 类不能直接使用,对象是可以直接使用的。

类与对象的定义

格式:

class 类名称{              //类的名称首字母大写
属性(变量)
行为(方法)
}

范例:定义一个Person类

class Person                       //类Person类名首字母大写
{
String name ;
int age ;

public void tell(){ //方法tell 没有static
System.out.println("姓名:" + name +",年龄:" + age);
}
}

定义完类之后,类无法直接被引用,必须依靠对象,

所以,对象的产生格式如下:

格式一:声明并实例化对象

类名称 对象名称 = new 类名称();

格式二:声明并实例化对象

声明对象: 类名称 对象名称 = null;

实例化对象: 对象名称 = new 类名称();

以后只要引用数据类型的实例化操作,永远都会存在关键字new分配空间),当一个实例化对象产生之后,可以按照如下的方式进行类的操作:

对象.属性:表示调用类之中的属性。

对象.方法():表示调用类之中的方法。

class Person                                   //类Person类名首字母大写
{
String name ;
int age ;
public void tell(){ //方法tell 没有static
System.out.println("姓名:" + name +",年龄:" + age);
}
}
public class TestDemo
{
public static void main(String args[]){
Person per = new Person() ; //声明实例化对象
//类名称 对象名称 = new 类名称();
per.name = "张三" ;
per.age = 30 ;
per.tell() ;
}
}
**方式1:**    
Person per = new Person() ; //声明实例化对象
//类名称 对象名称 = new 类名称();
**方式2:**
Person per = null ; //声明对象
per = new Person(); //实例化对象

堆内存:保存对象的真正数据,都是每一个对象的属性内容

栈内存:保存的是一块堆内存的空间地址,可以想象成一个int型变量(每一个int型变量只能存放一个数值),所以每一块保留一块内存

类与对象、引用传递、封装、构造方法、匿名对象笔记_实例化

类与对象、引用传递、封装、构造方法、匿名对象笔记_实例化_02

class Person                    //类Person类名首字母大写
{
String name ;
int age ;
public void tell(){ //方法tell 没有static
System.out.println("姓名:" + name +",年龄:" + age);
}
}
public class TestDemo
{
public static void main(String args[]){
Person per = null ; //声明对象
per.name = "张三" ;
per.age = 30 ;
per.tell() ;
}
}

这时候的程序发现:只声明了Person对象,但是并没有实例化Person对象(只有栈内存,并没有对应的堆内存空间),则程序在编译的时候不会出现任何错误,但是在执行的时候出现以下错误信息:

**Exception in thread “main” java.lang.NullPointerException

at TestDemo.main(TestDemo.java:21)**

这个错误信息表示的是NullPointerException(空指向异常)这种异常只会在引用数据类型上产生。

引用传递

class Person                    //类Person类名首字母大写
{
String name ;
int age ;
public void tell(){ //方法tell 没有static
System.out.println("姓名:" + name +",年龄:" + age);
}
}
public class TestDemo
{
public static void main(String args[]){
Person per1 = new Person();
per1.name = "张三" ;
per1.age = 30 ;
Person per2 = per1; **//引用传递**
per2.name = "李四" ;
per1.tell() ;
}
}

类与对象、引用传递、封装、构造方法、匿名对象笔记_类名_03

引用传递的精髓:同一块堆内存空间,同时被多个栈内存所指向,不同的栈可以修改同一块堆内存的内容。

范例分析:

类与对象、引用传递、封装、构造方法、匿名对象笔记_实例化_04

垃圾:指的是在程序开发过程中任何对象所指向的一块堆内存空间,这块空间就成为垃圾,所有垃圾将等待GC(垃圾收集器)不定期的进行回收与空间的释放。

封装

定义私有属性(private)→封装

class Person                    //类Person类名首字母大写
{
private String name ;
private int age ;

public void setName(String n){
name = n ;
}
public void setAge(int a){
if(a >= 0 && a <= 100){
age = a ;
}
}
public String getName(){
return name ;
}
public int getAge(){
return age ;
}
public void tell(){ //方法tell 没有static
System.out.println("姓名:" + name +",年龄:" + age);
}
}
public class TestDemo
{
public static void main(String args[]){
Person per = new Person() ;
per.setName("张三") ;
per.setAge(20) ;
per.tell() ;

System.out.println(per.getName()); //获取名字动作
}
}

按照java的开发标准来说,现在需要按照如下形式定义操作方法:setter、getter;

 Setter:(private String name):public void setName(String n);

 Getter:(private String name):public void getName();

以后再开发的时候,如果有需要,则在setter上加上一些验证措施,而getter方法只是简单的将数据返回即可,不需要做任何验证措施。

注意:在类之中的属性定义setter()、getter()操作方法目的就是为了设置和取得属性的内容,也许某一个操作暂时不使用到取得的操作,不过从开发来讲,必须全部提供,以后再定义类的时候,所有的属性都要编写成private封装,封装之后的属性如果被外部操作,则编写setter、getter。

构造方法

方法和属性的区分,方法之后存在”()”而属性后什么都没有

类名称 对象名称 = new 类名称() ;

针对每一个出现的标记进行解释:

类名称类名称 对象名称 = new 类名称() ;):要定义变量的数据类型;

对象名称(类名称 对象名称 = new 类名称() ;):指的是日后进行类属性或方法操作的名称;

new(类名称 对象名称 = new 类名称() ;):开辟堆内存空间;

类名称()(类名称 对象名称 = new 类名称() ;):解释如下:

加“()”的都是方法,但是这个“类名称()”比较特殊,称为构造方法,

构造方法与普通的方法的区别在于:

构造方法是在实例化对象的时候使用,而普通方法实在实例化对象产生之后使用的,

构造方法本身定义为:

 构造方法的名称和类的名称保持一致;

 构造方法不允许返回值类型声明;

 由于对象实例化操作一定需要构造方法的存在,所以如果在类之中没有明确定义构造方法的话,则会自动的生成一个无参的、无返回值的构造方法,并供用户使用,也就是说,一个类之中至少存在一个构造方法。

 构造方法在对象实例化的时候完成操作,而且一个对象的构造方法只会显示调用一次

class Person                    //类Person类名首字母大写
{
private String name ;
private int age ;
public Person(String n, int a){ //通过构造方法赋值
this.setName(n) ;
this.setAge(a) ; //调用本类之中的setName()方法,可以检查
}
//this可写可不写


public void setName(String n){
name = n ;
}
public void setAge(int a){
if( a >= 0 && a <= 100 ){
age = a ;
}
}
public String getName(){
return name ;
}
public int getAge(){
return age ;
}
public void tell(){ //方法tell 没有static
System.out.println("姓名:" + name +",年龄:" + age);
}
}

public class TestDemo
{
public static void main(String args[]){
Person per = new Person("张三", 20) ; //声明并实例化对象
per.tell() ;

}
}

在实际之中构造方法的主要作用只有一点:那就是在对象实例化的时候为类之中的属性初始化。

下面便是类中对属性的初始化过程:

public Person(String  n ,  int  a){
name = n;
age = a ;
}

构造方法的重载只需要考虑方法内的参数的个数、类型。

注意:构造方法重载时一般按照参数的个数排列;由多到少,由少到多。

构造方法属于整个对象构造过程的最后一步,对象的构造需要为其分配空间,之后再设置成默认值,最后留给构造方法进行其他操作,所以可以定义的构造方法是对象实例化的最后一步,而其他的几步用户根本看不见,也无法进行操作。

匿名对象

class Person                    //类Person类名首字母大写
{
private String name ;
private int age ;
public Person(String n, int a){ //通过构造方法赋值
name = n ;
age = a ;
}
public void tell(){ //方法tell 没有static
System.out.println("姓名:" + name +",年龄:" + age);
}
}
public class TestDemo
{
public static void main(String args[]){
new Person("张三", 20).tell() ; //匿名对象
}
}

匿名对象由于没有对应的栈内存指向,所以只能使用一次,一次之后就将成为垃圾,并且等待GC回收释放。