Java面向对象详解(上)
面向对象思想概述
面向过程和面向对象的区别
在java中有这样一句话“一切皆对象”,Java是一门纯粹的面向对象思想的语言,我们也常常听到还有“面向过程思想”,例如c语言就是这种思想。那么我们应该如何去理解面向过程思想,面向对象思想,以及它们之间有何区别呢?
比如小红同学她想吃棉花糖,然后她购买原材料、学习如何制作、使用工具制作棉花糖、吃糖,这么一系列的过程就叫面向过程,分析问题将问题的过程一一表述出来。那么什么是面向对象呢,小红响彻棉花糖,于是她取找了一个卖棉花糖的店,让师傅给她做了一个棉花糖,而制作棉花糖的过程,什么原料需要什么过程她都不需要了解,她也吃到了棉花糖。这就是面向对象思想,找个一个对象通过对象来解决问题。
类和对象
使用面向对象的思想解决问题,那么肯定需要一个对象。对象是一类具体事物的实例实现。类,用来表现一类事物的统称,是一个抽象的概念。我的理解是类是一类事物的模板,描述了事物的属性和行为动作,而对象具体化了属性值和哪些动作,是一个具体的实例化的类。类是对象的模板,对象是类的实例。所以必须先创建类,然后菜可以创建对象出来。Java中使用class关键字表示类,使用new 关键字创建对象。
类、对象的创建和使用
类是由属性和行为两部分组成。
属性:类中的成员属性,位于类体中,方法外。
行为:使用方法表示行为。
//类体 class关键字 Person类名(首字母大写,驼峰命名) class Person{ //属性(成员变量) 变量类型 变量名 String name; int age; //类体中,方法外 //行为(成员方法) 方法 void eat(){ System.out.printLn(name+"在吃饭"); } int getAge(){ return age; } }
创建类后,如何创建出这个类的对象呢,如何使用这个对象呢。
创建对象使用 类名 对象名 = new 类名 (); 得到对象的成员变量 对象名.属性名; 调用对象的方法 对象名.方法名; public static void main(String []args){ Person person = new Person(); //创建对象 person.name = "张三"; person.age = 18; //对象属性赋值 person的名字为张三年龄为18 pserson.eat(); //对象调用方法 张三吃饭 }
成员属性的默认初始值
从上面Person类可以得知name和age属性成员变量不必直接进行初始化,实际上创建对象时jvm会对对象的属性进行默认初始化,那么我们就来测试下各种类型不同的默认值吧。
/**创建Test测试类,分别对基本类型和引用类型进行测试*/ public class Test { //基本类型 //整型 byte aByte; short aShort; int anInt; long aLong; //浮点型 float aFloat; double aDouble; //字符型 char aChar; //布尔型 boolean aBoolean; //引用类型 //字符串 String aString; //数组 int [] arr; } //创建Test对象,测试默认初始值
成员变量可以不给初始值,是存在默认值的,在创建对象时会对其赋值默认初始化值。
数据类型 默认值 基本数据类型 整型(byte、short、int、long) 0 浮点型(float、double) 0.0 字符型(char) '\u0000'或 0 布尔型(boolean) false 引用类型 String、数组、类、接口 null 内存图
使用new Person()创建一个Person对象时,jvm会在堆内存中创建一个Person对象,这时,Person person=new Person(),栈空间中的Person类型的person引用就会指向堆内存中的Person对象的地址。
这时person对象创建出来了,但还没由对person对象进行赋值,这时堆内存中的person对象的两个属性name,age分别为null和0,执行person.name = "张三";和person.age = 18;"张三"和18会分别覆盖掉null和0。这时person对象有值了,这时访问person.name或者person.age就能分别打印出"张三"和18了。对象调用方法时,就会到一个堆方法区的堆栈中了。先进入main()方法压栈,执行person.eat();eat方法就会进入栈中,执行完毕出栈,在执行下一个方法在入栈,直到执行完毕main()方法出栈。
但多个引用指向同一个对象时,实际上就是多个对象的引用指向了堆内存中的同一个内存空间,变量所记录的地址值是相同的。只有在使用new关键字创建了对象,才会在堆内存中开辟一个对象空间。所以只要有一个对象引用拿着地址去修改了对象的值,那么内存中对象的值就改变了,随后的每个引用访问的这个对象的对应值都是修改之后的。
成员变量和局部变量的区别
根据变量在类中的位置不同,我们将变量分为成员变量和局部变量,同样方法的参数也有形参和实参。
public class Car{ //变量在类体中,方法外称为成员变量 String name; int price; .... public void run(String name//形参,也属于局部变量){ int price = 10000; //方法中的变量,被称为局部变量 ... } }
区别 成员变量 局部变量 在类中的位置 类中方法外 方法中,形参 作用范围 类中 方法中 初始值 默认值 没有默认值,必须先定义赋值才能使用 在内存中的位置 堆内存 栈内存 生命周期 随对象的创建而存在,随着对象的消失而消失 随着方法的调用而存在,随着方法的调用结束而消失 java只有值传递
封装
面向对象的重要特征之一:封装。既然在类中定义成员变量和方法是为了方便使用,那么为什么要设定限定修饰符来修饰变量和方法呢。这是为了不让别的类随意调用和随意破坏对象的数据,所以将数据进行封装起来,细节隐藏起来,那么如何能够访问隐藏起来的数据,将数据的访问和赋值交给方法来实现,使用赋值和访问方法来类的属性进行赋值,这就是封装,为了数据的安全。原则:合理隐藏,合理暴露。实现方法:我们需要将成员变量(属性)隐藏起来,若需要访问某个成员变量,暴露公共方法对其访问。我们可以在赋值的时候对值进行检测,虽然平时不这样做。
public class Student{ private String name; private int age; public String getName(){ return this.name; } public void SetName(String name){ this.name = name; } public int getAge(){ return this.age; } public void SetAge(){ this.age = age; } }
封装的使用步骤:
1.将成员变量使用private修饰,private修饰的成员变量只能在当前类使用,而不能对别的类使用。
2.使用private将变量封装起来,将访问和赋值方法使用public修饰供别人使用,getter/setter方法具有固定的格式,getter方法将访问该方法的对应成员变量值获取到,所以getter方法具有一个对应成员变量类型的返回值,getter方法的格式是get+属性(首字母大写),setter方法就是将对应类型的值赋值给那个成员变量,所以没有方法值但有参入参数,setter方法的格式set+属性名(首字母大写)。
在idea中使用alt+insert组合键可以打开generate生成构造方法,getter和setter方法,toString()方法
this关键字的使用
this的使用方法:
1.表示当前类对象的引用
2.在当前方法中局部变量和成员变量名称相同时,就近原则,局部变量会覆盖掉成员变量,使用this指向当前对象。