Java基础——类与对象

每日正能量

        成功的信念在人脑中的作用就如闹钟,会在你需要时将你唤醒。 

类和对象

【本章内容】1. 对象的概念2. 类的概念3. 构造方法4. 方法的重载
【能力目标】1. 能够定义类,能够实例化对象2. 能够理解构造用于初始化属性3. 能够定义和使用包4. 了解Java常用系统包

 

用现有的技术解决这个问题:

(1) 使用单独变量解决

(2) 使用数组解决

缺点:

(1)不利于数据的管理

(2)效率低下

        在面向对象编程中,类是组成程序的基本单位,程序功能的实现是通过对象自身和对象之间的交互来完成的。在Java中要先定义类,通过实例类来创建对象。类是对象的模板,用来定义对象的属性和方法。从本章开始,我们将进入面向对象程序设计的世界。

1.什么是对象

面向对象程序设计(Object Oriented Programming,OOP)是一种基于对象概念的软件开发方法,是目前软件开发的主流方法。

那么什么是对象呢?在面向对象的世界中认为万事万物皆对象。也就是说能看得见,摸得着的任何物品都是对象。例如猫、狗、鸭子等。在面向对象的世界中认识对象是从两个方面进行的,一是对象有什么状态、二是对象有什么行为。对象的状态是指对象本身固有的属性。例如猫有年龄、体重、毛色。对象的行为是指对象具有哪些功能。例如猫有捉老鼠、上树、跳跃等行为。

总而言之对象是具体的

2.什么是类

类是具有相同的状态和相同的行为的一组对象的集合。例如有身高,有体重,有姓名,有学号的状态,有听课,有做作业的行为的所有对象可以归纳为同一类,即学生类。日常生活中我们经常不知觉的进行分类,如:坏人、英雄,数据类型。

在编程的世界中,用属性表示对象的状态,用方法表示对象的行为。要创建对象必须先定义类,通过类可以实例化出对象。类是对象的模板,对象是类的具体实例。属性也称为类的成员变量,方法也称为类的成员方法。

而类是抽象的

3.定义类

Java是一种纯粹的面向对象的语言,每一个程序至少包含一个类,所有的数据(属性)和操作(行为)都封装到类中。类要先声明再使用。

类的声明形式如下

class 类名{

成员变量声明;//即属性

成员方法声明;//即行为

}

说明:

类的声明包括类首和类主体两部分。

  1. 类首确定类名,其中class是声明类的关键字,类名首字母大写。

  2. 类主体包括成员变量和成员方法。

例如:声明一个学生类,命名为Student,类中包含学生姓名属性和成绩属性,包含自我介绍的方法。为了描述这个类的构成,给出下面的类图。

 

根据类图,将Student类定义如下:

public class Student {
    String name;  //定义姓名属性  
    int score;    //定义成绩属性
    /**  
    * 自我介绍方法     
    */
    public void introduce(){
        System.out.println("大家好,我叫"+name+",我的成绩是"+score);   
    }
}

说明

  1. 定义了类Student,定义一个类可以理解为定义了一个新的数据类型。

  2. 在Student类中定义了name属性和score属性和introduce方法。

4.定义对象

定义类以后可以创建类的对象,对象的创建分为两步,第一是对象的声明,第二是对象的实例化。

对象的声明如下

类名 对象名;

对象的实例化如下:

对象名 = new 类名(参数列表);

也可以将对象的声明和对象的实例化写在一起,如下:

类名 对象名 = new 类名(参数列表);

说明

  1. 使用new运算符实例化对象

  2. 实例化对象就是为对象的属性分配内存。

代码演示对象声明与对象实例化

Student stu;  //对象声明
stu =new Student();//对象实例化
//或
Student stu=new Student();  //对象的声明和实例化

说明:

  1. Student stu表示定义Student类的对象stu,其实就是定义一个Student类型的变量stu,通常基本类型定义的叫变量,引用类型定义的叫对象,除了基本类型以外的都是引用类型。

  2. stu =new Student()表示对stu对象实例化,即为stu对象的name属性和score属性分配内存。

5. 使用对象

对象创建后,这个对象就拥有所属类的变量和方法,对象就可以调用变量和方法。调用属性和方法使用成员运算符“.”。

Student stu = null;
stu =new Student();
stu.name = "林冲";  //stu对象调用name属性,为name属性赋值
stu.score=86;    //stu对象调用score属性,为score属性赋值
stu.introduce();   //stu对象调用introduce()方法
任务1:李冲和鲁智深自我介绍
定义学生类,包含name属性和score属性和introduce方法,在introduce方法中实现自我介绍。

代码示例

public class Student {
    String name; //定义姓名属性   
    int score;    //定义成绩属性
    //自我介绍方法
    public void introduce(){
        System.out.println("大家好,我叫"+name+",我的成绩是"+score);   
    }   
    public static void main(String[] args) {
        Student stu1 = null;
        stu1 = new Student();
        stu1.name = "林冲";
        stu1.score= 86;
        stu1.introduce();
        Student stu2 = null;
        stu2 = new Student();
        stu2.name = "鲁智深";
        stu2.score=90;
        stu2.introduce();
    }
}

运行结果

大家好,我叫林冲,我的成绩是86

大家好,我叫鲁智深,我的成绩是90

带你分析代码:

 

  1. java把内存分成多个区域,其中包括堆和栈,对象的声明被分配在栈内存中,对象的实例化(new)被分配在堆内存中。对象的实例化其实就是为对象的属性分配内存。本例中实例化stu1时就是在为stu1的name属性和score属性分配内存。可以理解为new就是在分配内存。

  2. Student stu1 = null;表示声明一个Student类型的对象stu1,此时java会在内存栈区分配一个存储单元给对象stu1,本例中将内存单元为0xFF02的单元分配给stu1对象。

  3. stu1 =new Student();表示为stu1对象实例化,此时java会在内存的堆区为stu1的属性name和score分配内存。本例中将内存单元为0xAA01和0xAA02分别分配给stu1的name属性和score属性。并将分配内存的首地址编号0xAA01赋给对象stu1的存储单元,即stu1指向到0xAA01地址。

  4. stu1.name = "林冲";是将字符串"林冲"赋值给stu1的name属性。

  5. stu1.score=86;是将整数86赋值给stu1的score属性。

  6. stu1.introduce();让stu1对象调用introduce方法,在方法内部读取了stu1的name属性和score属性的值并打印到控制台。

  7. stu2的定义和使用同上

练习:声明Person类,属性:name,age,high,行为:睡觉,自我介绍

有10个人,创建对象的方式表示10个人的信息,调用10个人行为。

任务2:探索空指针异常NullPointerException
异常是指程序编写时或者运行时发生的错误。空指针是常见的错误,下面的例子研究空指针产生的原因。

代码示例

public class Student {
    String name; //定义姓名属性   
    int score;    //定义成绩属性  
    /**
    * 自我介绍方法
    */
    public void introduce(){
        System.out.println("大家好,我叫"+name+",我的成绩是"+score);   
    }
    public static void main(String[] args) {
        Student stu1 = null;
        stu1.name = "林冲";
        stu1.score=86;
        stu1.introduce();
    }
}

运行结果

Exception in thread "main" java.lang.NullPointerException at com.myblog.biz.Student.main(Student.java:15)

带你分析代码

 

  1. Student stu1 = null;表示声明一个Student类型的对象stu1,此时java会在内存栈区分配一个存储单元给对象stu1,本例中将内存单元为0xFF02的单元分配给stu1对象。

注意:此时还没有实例化对象stu1(没有new),因此stu1对象的name属性和score属性还没有分配内存。此时对象stu1所在的内存单元0xff02地址中的值是默认值null,null表示空指针,即stu1没有指向到堆内存中。

  1. stu1.name = "林冲";表示将字符串"林冲"赋值给stu1指向堆中的内存单元,但由于stu1是空指针,因此无法将"林冲"赋值给stu1的name属性,java虚拟机抛出空指针异常。

  2. 造成空指针的原因就是对象没有实例化,即对象没有new。

6. 方法重载overload

在一个类中,多个方法具有相同的方法名称,但却具有不同的参数列表,与返回值无关,称作方法重载。程序运行时,根据参数列表匹配原则决定执行那个方法。参数匹配是指参数个数,参数类型,参数顺序一致。重载表现为同一个类中的方法的多态性。

以下是正确的方法重载

public double area(double a);

public double area(int a,double b)

public double area(double a,int b)

以下是不正确的方法重载

public int calc(int a,int b)

public void calc(int x,int y)

因为两个方法虽然返回值类型和参数名称不同,但参数个数、类型和顺序完全相同,也就是说参数列表相同。

通过方法重载,采用统一的方法名称可以执行不同的方法体。例如,计算圆形、三角形、长方形的面积时,可以定义具有以下方法的重载。

public double area(double r)

public double area(double a,double b,double c)

public double area(double a,double b)

如果不使用方法重载,需要定义3个不同的方法名,调用时不方便。

7. 方法可变参数

在Java程序设计中,当遇到不确定数量的方法参数时,可以使用数组作为方法的参数。在Java5中,允许定义可变参数。定义方法时,在最后一个形参的类型后增加三点(…),则表明该形参可以接受多个参数值,多个参数值被当做数组传入。

任务7:方法可变参数

public class Task7 {    
    public static void sum(String name, int... scores) {        
        int sum = 0;    
        System.out.println(name+"的第一门功课成绩是:"+scores[0]);        
        for (int i = 0; i < scores.length; i++) {
            sum += scores[i];
        }
        System.out.println(name + "的总成绩是:" + sum);
    }   
    public static void main(String[] args) {        
        sum("宋江", 90, 70, 88, 98);      
        int[] scores = { 80, 60, 69, 66, 77 };      
        sum("阎惜娇", scores); 
    }
}

8. 构造方法与对象初始化

Student stu1 = null;  声明stu1对象
stu1 = new Student();  实例化stu1对象
stu1.name = "林冲";   为stu1的name属性赋值
stu1.score=86;     为stu1的score属性赋值

上面的代码将stu1的实例化和为属性赋值是分开写的,能不能在实例化stu1的同时就为stu1的name属性和score属性初始化呢?答案是可以的,这就需要使用构造函数。

类中有一种特殊的成员方法,其方法名与类名相同,没有返回值类型,也不写void,这个成员方法叫构造方法,也叫构造函数。

构造方法的作用是为对象的属性初始化。构造方法不允许使用对象调用,只能是在用new运算符实例化对象时自动调用。如果没有声明构造方法,系统会为类生成一个无参数的默认构造方法。默认构造函数为类的属性初始化为默认值,整型默认值为0,浮点型默认值为0.0,布尔型默认值是false,字符型默认值是'\u0000',引用类型默认值为null。如果自定义了构造方法,系统默认的构造方法就不存在了。一个类可以声明多个构造方法,但各构造方法的参数不允许相同,在使用new运算符实例化对象时,根据参数匹配原则调用相应的构造方法。

可见构造方法与其它成员方法不同之处是:

  1. 作用不同:构造方法仅用于实例化对象,对成员变量进行初始化,成员方法用于对成员变量进行多种操作。

  2. 调用方式不同:构造方法只能通过new运算符调用,成员方法可以通过对象调用。

任务3:通过构造方法为属性初始化
将Student类重构,定义两个构造方法初始化对象的属性。

代码示例

public class Student {  
    String name; //定义姓名属性   
    int score;    //定义成绩属性  
    public Student(String name){
        this.name = name;
    }
    public Student(String name,int score){      
        this.name =name;        
        this.score = score;
    }
    /**
    * 自我介绍方法     
    */
    public void introduce(){
        System.out.println("大家好,我叫"+name+",我的成绩是"+score);
    }
    public static void main(String[] args) {
        Student stu1 = new Student("林冲");
        stu1.introduce(); 
        Student stu2 = new Student("鲁智深",90);
        stu2.introduce();   
    }
}

带你分析代码

  1. Student类中定义了两个构造方法public Student(String name)和public Student(String name,int score)。

  2. Student stu1 = new Student("林冲");代码在使用new运算符创建对象,由于实际参数是一个String类型的数据"林冲",因此在实例化时会调用有一个String类型参数的构造方法,即public Student(String name),并且将实际参数"林冲"赋值给形式参数name。

  3. 构造函数中的this.name = name;中的this是java中的关键字,指当前正在运行的对象,本例中实例化的对象是stu1,因此this指代stu1对象。即将"林冲"赋值给了stu1的name属性。

  4. Student stu2 = new Student("鲁智深",90) ;代码在使用new运算符创建对象,由于实际参数有两个,第一个是String类型的"鲁智深",另一个是int类型的90,因此new运算符会调用有两个参数的构造函数,第一个参数是String类型,第二个参数是int类型。并将实际参数"鲁智深"赋值给形式参数name,实际参数90赋值给形式参数score。

  • 4
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值