类与对象
类与对象的基本概念
类:是抽象的概念集合,表示的是一个共性的产物,类中定义的是属性和行为(方法);(不能用)
对象:对象是一种个性的表示,表示一个独立的个体,每个对象拥有自己独立的属性,依靠属性来区分不同的对象。(能用)
区别:类是对象的模板,对象是类的实例,类是通过对象才可以使用的,而在开发之中应该先产生类,之后再产生对象。
注意: 类不能直接使用,对象是可以直接使用的。
类与对象的定义
格式:
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型变量只能存放一个数值),所以每一块保留一块内存
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() ;
}
}
引用传递的精髓:同一块堆内存空间,同时被多个栈内存所指向,不同的栈可以修改同一块堆内存的内容。
范例分析:
垃圾:指的是在程序开发过程中任何对象所指向的一块堆内存空间,这块空间就成为垃圾,所有垃圾将等待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回收释放。