Java编程基础-面向对象(上)

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java编程基础-面向对象(上)相关的知识,希望对你有一定的参考价值。

一、面向对象的概念

1、概念:面向对象是把解决的问题按照一定规则划分为多个独立的对象,然后通过调用对象的方法来解决问题。当然,一个应用程序会包含多个对象,通过多个对象的相互配合来实现应用程序的功能。这样当应用程序功能发生变动时,只需要修改个别对象就可以了,从而使代码更容易得到维护。面向对象强调的是对象,它使复杂的内容简单化了,让我们从执行者变成了指挥者。

2、特点:面向对象的特点概括起来就是继承性、封装性和多态性。

3、 封装性:封装是面向对象的核心思想,将对象的属性和行为封装起来,不需要让外界直到具体实现细节,这就是封装思想。(example:用户使用电脑,只要用手指敲击键盘就行了,不需要知道电脑内部是如何工作的。)封装隐藏了对象的属性实现的细节,仅对外提供公共访问形式。好处是将变化隔离,便于使用,提高重用性和安全性。

 封装的原则:将不需要对外提供的内容都隐藏起来,把属性都隐藏,提供公共方法对其访问。

 

二、类的定义

1、类与对象:类是对某一类事物的抽象描述,而对象用于表示现实中该类事物的个体。也可以说类是一组相关的属性和行为的集合(成员变量和方法)。Java中最基本的单位是类。

2、类的定义内容:类是对象的抽象,它用于描述一组对象的共同特征和行为。类中可以定义成员变量和成员方法,其中成员变量用于描述对象的特征,也被称作属性,成员方法用于描述对象的行为,可简称为方法或函数。

代码示例:

  1. public class Student {// class关键字表示类,后面紧跟类名,Student是类名,表示声明一个公有的学生类  
  2.     // 定义属性  
  3.     String name;// 成员变量name-->姓名,String是该变量的类型  
  4.     int age; // 成员变量age-->年龄,int是该变量的类型  
  5.   
  6.     // 定义成员方法(函数)  
  7.     public void study() {// 定义一个学习方法  
  8.         System.out.println(name + "正在学习!");  
  9.         // 在成员方法study()中可以直接访问成员变量name  
  10.     }  
  11.   
  12. }  

注意:在java中,定义在类中的变量被称为成员变量,定义在方法中的变量被称为局部变量,如果在某一个方法中定义的局部变量与成员变量同名,这种情况是允许的,此时方法中通过变量名访问到的是局部变量,而并非成员变量。

 

三、创建与使用对象

1、创建对象:程序想要完成具体的功能,仅有类是远远不够的,还需要根据类创建实例对象。在java中可以使用new关键字来创建对象。创建对象的过程也称实例化。具体格式如下:

类型  变量名=new 类名();

如创建一个Student类的对象:Student stu=new Student();

在上面代码中,“new Student() “用于创建Student类的一个实例对象,” Student stu “则是声明了一个Student类型变量stu。中间等号用于将Student对象在内存中的地址值赋值给变量stu,这样变量stu便持有了对象的引用。

2、属性的赋值和访问:

赋值语法-->变量名.属性名=属性值;   

访问语法-->变量名.属性名  

3、方法的调用:变量名.方法名(<param>,..),如果该方法需要参数,则加入相应的参数。

4、成员变量的默认初始化值:在实例化对象时,java虚拟机会自动为成员变量进行初始化,针对不同类型的成员变量,java虚拟机会赋予不同的初始值。

byte、short和int类型的成员变量默认初始化值为0,long类型成员变量默认初始化值为0L,float和double类型成员变量的默认初始化值分别为0.0f和0.0d,char类型默认为空字符,boolean类型默认为false,引用类型默认为null.

代码示例:

  1. public class Student {  
  2.   
  3.     String name;// 成员变量name-->姓名,String是该变量的类型  
  4.     int age; // 成员变量age-->年龄,int是该变量的类型  
  5.   
  6.     public void study() {// 定义一个学习方法  
  7.         int age = 21;// 同名的局部变量  
  8.         System.out.println(age + "岁的" + name + "正在学习!");  
  9.   
  10.     }  
  11. }  

测试:

  1. public static void main(String[] args) {  
  2.         Student stu1 = new Student();// 创建第一个学生实例  
  3.         stu1.name = "张三";// 给第一个学生名字初始化为张三  
  4.         System.out.println(stu1.name + " " + stu1.age);// 打印第一个学生的姓名和年龄  
  5.         stu1.study();// 调用study()方法  
  6.         Student stu2 = new Student();// 创建第二个学生实例  
  7.         stu2.study();// 调用study()方法  
  8.   
  9.     }  


输出结果为:

张三 0
21岁的张三正在学习!
21岁的null正在学习!

简单分析:由于第一个学生对象的年龄并没有初始化,所以系统会使用默认值,int类型的默认值为0,所以输出结果为 :张三 0

由于在study()方法中定义了同名的局部变量age,所以第一个学生对象在调用该方法是访问的是局部变量的age,而不是成员变量的age。所以输出21岁的张三正在学习!

第二个学生对象由于name属性没有赋初值,所以使用默认值null,同样调用study()方法访问的是局部变量age,所以输出结果为:21岁的null正在学习!
5、成员变量和局部变量的区别:

a)在作用域上,成员变量的作用域是整个类中都可以访问,而局部变量的作用域是定义它的方法内或语句中,执行完它就会被回收。

b)初始值,成员变量有默认初始化值,局部变量是没有默认初始化值的,必须定义、赋值,然后才能使用。

c)所在内存区域,成员变量在对象里,对象在堆内存里,成员变量也在堆里,不使用的对象会被垃圾回收机制在不确定的时候回收。而局部变量在方法运行的栈内存里,会自动释放。

d)生命周期,成员变量随着对象的创建而存在,随着对象的消失而消失。局部变量随着方法的调用而存在随着方法调用完毕而消失。


四、类的封装

1、类的封装:所谓类的封装是指在定义一个类时将类中的属性私有化,即使用private关键字来修饰,私有属性只能在它所在类中被访问,为了能让外界访问私有属性需要提供一些使用public修饰的公有方法,其中包括用于获取属性值的getXXX方法和设置属性值的setXXX方法。

注意:private仅仅是封装的一种体现,不能说封装就是私有,私有的访问权限最低,只有在本类中访问有效,比如protected也可以是实现封装。封装是一种思想,将具体实现隐藏,仅对外暴露访问方式。private修饰后的成员变量和成员方法,它们都不能在其他类中直接访问。

代码示例:

  1. public class Student {  
  2.   
  3.     private String name;// 将name属性私有化  
  4.     private int age;// 将age属性私有化  
  5.   
  6.     // 下面是公有的setXXX和getXXX方法  
  7.     public String getName() {  
  8.         return name;  
  9.     }  
  10.   
  11.     public void setName(String name) {  
  12.         this.name = name;  
  13.     }  
  14.   
  15.     public int getAge() {  
  16.         return age;  
  17.     }  
  18.   
  19.     public void setAge(int age) {  
  20.         this.age = age;  
  21.     }  
  22.   
  23.     public void study() {  
  24.         System.out.println("正在学习的" + name + ",今年" + age + "岁。");  
  25.     }  
  26.   
  27. }  

测试:

  1. public class Test {  
  2.   
  3.     public static void main(String[] args) {  
  4.         Student stu = new Student();// 创建Student对象  
  5.         stu.setName("张三");// 调用setName()方法赋值  
  6.         stu.setAge(21);// 调用setAge()方法赋值  
  7.         stu.study();// 调用study()方法  
  8.         System.out.println(stu.getName() + " " + stu.getAge());// 获取姓名和年龄  
  9.   
  10.     }  
  11.   
  12. }  

输出结果为:

正在学习的张三,今年21岁。
张三 21

五、构造方法

1、前言:从前面所学知识可以发现,实例化一个对象后,如果要为这个对象中的属性赋值,必须通过直接访问对象的属性或调用setXXX方法的方式才可以。如果需要在实例化对象的同时就为这个对象的属性进行赋值,可以通过构造方法来实现。构造方法是类的一个特殊成员,它会在类实例化对象时被自动调用。

2、构造函数的满足条件:在一个类中定义的方法如果同时满足以下三个条件,该方法称为构造方法。

方法名与类名相同(大小写也要与类名一致),在方法名的前面没有返回值类型的声明(没有void),在方法中不能使用return语句返回一个值。

 作用:用于给对象的属性进行初始化

代码示例:

  1. public class Student {  
  2.   
  3.     private String name;// 将name属性私有化  
  4.     private int age;// 将age属性私有化  
  5.   
  6.     public Student() {  
  7.         System.out.println("无参的构造函数被调用了");  
  8.     }  
  9.   
  10.     public Student(String n) {  
  11.         name = n;  
  12.     }  
  13.   
  14.     public void study() {  
  15.         System.out.println("正在学习的是" + name);  
  16.     }  
  17.   
  18. }  

测试:

  1. public class Test {  
  2.   
  3.     public static void main(String[] args) {  
  4.         Student stu1 = new Student();// 创建Student对象  
  5.         Student stu2 = new Student("张三丰");  
  6.         stu2.study();  
  7.   
  8.     }  
  9.   
  10. }  

输出结果为:

无参的构造函数被调用了
正在学习的是张三丰

简单分析:创建第一个学生对象的同时调用了无参的构造方法Student(),执行了方法中的打印输出语句。创建第二个学生对象的同时调用了带一个int类型参数的构造方法,执行了该方法中的语句,将实际参数传递给成员变量age,所以调用study()方法时访问的是已经初始化后的成员变量name的值。

注意:

a) 当一个类中没有定义构造函数时,系统会默认给该类加入一个空参数的构造函数。如果定义了构造函数,无论是有参还是无参,系统都不会再给默认的构造函数了。

b)重载的构造方法是根据参数列表来区分是哪个构造方法。多个构造函数以重载形式存在。

c)构造函数间的调用只能用this语句。

d) 对象一建立就会调用与之对应的构造函数。

3、构造函数的重载:与普通方法一样,构造方法也可以重载,在一个类中可以定义多个构造方法,只要每个构造方法测参数类型或参数个数不同即可。在创建对象时,可以通过调用不同的构造方法来为不同属性进行赋值。如上面代码示例中所示,根据参数的不同分别调用了不同的构造函数。

4、构造函数与一般函数的区别:

a)构造函数和一般函数书写格式上有所不同,运行上也有不同。

b)构造函数是在对象一建立就运行,给对象初始化。而一般方法是对象调用才执行,是给对象添加对象具备的功能。

c)一个对象建立,构造函数只运行一次。而一般方法可以被该对象调用多次。

在实际中,一般都要写一个空参数的构造函数。


六、this关键字

1、this:每个对象都有一个指向自己的指针,就是this。this代表所在函数所属对象的应用。简单说:哪个对象在调用this所在函数,this就代表哪个对象。

this:用于区分局部变量和成员变量同名情况。

2、三种常见用法:

(1)、 通过this关键字可以明确的去访问一个类的成员变量,解决与局部变量名称冲突问题。

  1. public class Student {  
  2.   
  3.     private int age;// 将age属性私有化  
  4.   
  5.     public Student() {  
  6.         super();  
  7.     }  
  8.   
  9.     public Student(int age) {  
  10.         super();  
  11.         this.age = age;  
  12.     }  
  13.   
  14.     public int getAge() {  
  15.         return age;  
  16.     }  
  17.   
  18.     public void setAge(int age) {  
  19.         this.age = age;  
  20.     }  
  21. }  

构造方法的参数被定义为age,它是一个局部变量,它与类中的成员变量名称相同,在构造方法中使用age,访问的是局部变量,但如果使用this.age,则访问的是成员变量。

(2)、通过this关键字调用成员方法。

  1. public class Student {  
  2.     public void study() {  
  3.         // .......  
  4.     }  
  5.   
  6.     public void sleep() {  
  7.         // study();//省略this也可以  
  8.         this.study();  
  9.     }  
  10. }  

在上面sleep()方法中,使用this关键字调用study()方法。this.study();和study();效果完全一样

(3)、 构造方法是在实例化对象时被java虚拟机自动调用的,在程序中不能像调用其他方法一样去调用构造方法,但可以在构造方法中使用”this([参数1,参数2,..])”的形式来调用其它的构造方法。

  1. public class Student {  
  2.     private String name;  
  3.     public Student()  
  4.     {  
  5.         System.out.println("无参的构造函数被调用了");  
  6.     }  
  7.     public Student(String name)  
  8.     {  
  9.         this();//调用无参的构造方法  
  10.         System.out.println("有参的构造函数被调用了");  
  11.     }  
  12. }  
  1. public class Test {  
  2.   
  3.     public static void main(String[] args) {      
  4.         Student stu = new Student("张三");  
  5.     }  
  6. }  

输出结果为:

无参的构造函数被调用了
有参的构造函数被调用了

3、在使用this调用构造方法时,应注意以下几点:

a)    只能在构造方法中使用this调用其它的构造方法,不能在成员方法中使用。

b)   在构造方法中,使用this调用构造方法的语句必须位于第一行,且只能出现一次。

c)    不能在一个类的两个构造方法中不能使用this互相调用。


七、垃圾回收

1、垃圾回收机制:在java中,当一个对象成为垃圾后仍会占用内存空间,时间一长,就会导致内存空间不足。针对这种情况,java引入了垃圾回收机制。Java虚拟机会自动回收垃圾对象所占用的内存空间。一个对象在成为垃圾后会暂时的保留在内存中,当这样的垃圾积累到一定程度时,java虚拟机就会启动垃圾回收器将这些垃圾对象从内存中释放,从而使程序获得更多可用的内存空间。除了等待java虚拟机进行自动垃圾回收,也可以通过调用System.gc()方法来通知java虚拟机立即进行垃圾回收。当一个对象在内存中被释放时,它的finalize()方法会被自动调用,因此可以在类中定义finalize()方法来观察对象何时被释放。













以上是关于Java编程基础-面向对象(上)的主要内容,如果未能解决你的问题,请参考以下文章

Java编程基础-面向对象(中)

JavaScript 精粹 基础 进阶OOP面向对象编程(上)

Java基础教程:面向对象编程

Java---面向对象基础

java基础面向对象编程

JAVA学习:Java面向对象编程基础