新手上路,欢迎指正
–lx
——“Java是一种纯面向对象的高级编程语言。”
抽象
在Java语言编程的过程中,需要将一系列编程目标转变成对象。抽象在书本上的含义是:“从被研究对象中舍弃个别的、非本质的问题或与研究主旨无关的次要特征。”简而言之就是从目标对象的所有属性中选取我们需要的。如果需要编写计算汽车高度的程序,我们就只需将汽车高度这一属性以及其数值相关的属性保留在程序创建的类中。
简谈面对对象编程
我认为其中的难点应该在于对象模板的建立,这其中涉及到了个性和共性的问题,并不是所有时候我们面对的编程目标都是如同汽车此类存在于现实中属性确定的对象。大多数时候我们需要从编程需求中找出共性,甄别个性,合理地保留和舍去后抽象出符合编程目标的对象模板——类。
类与对象
了解了抽象这一行为的含义后,类与对象的关系便很是清晰了。
假如我们只研究人的身高体重,那么在编程中“人”的类应该如下。
这里的类就是一个研究对象的“模板”,也可以称之为对象的共性。在现实中,我们无法找到两片完全相同的树叶,程序设计时的对象也是如此,共性之外同种对象还拥有自己的个性(防杠tips:即使对象完全数据一样,对于设备来说这些“孪生”对引用象还是有区别,例如内存占用地址)。同时由此可知,对象就是类这个模板的实例化产物,以下代码行便能见证类对象“张三”的“诞生”。
对象与对象引用
在Java语言中,原本属于c中稳定性和安全性较难把控的指针已经被弃用,但引用这一概念被保留并发展了。Java语言中的引用相较语言C来说,在某种层面上仿佛被“指针化”。引用能通过消息来与对象产生联系并具有“改变”对象的功能,类似于一种远程操纵。用一种不恰当的比喻,如果编程是一场战争,那么程序员就好比一位指挥官,对象是前线艰苦奋战的战士,对象引用就是指挥官与前线之间的通讯员。
People zhangSan;
上面这一行代码并没有创建类的对象,而是表示的是类的对象引用的创建,目前它没有任何指向,并且如果该语句定义在方法中,它的储存位置将位于栈内。
zhangSan=new People(180,100);
此处的语句为People类产生了实例化对象,并且使对象引用“zhangSan”指向了该对象。所以从某种角度来说“张三”并非“张三”,而是用于指代实例化对象的一个引用名称,就好比每个人的名字不是生来就拥有的,而是后天赋予,名字可以指代你,但不能替代你(有点扯辽,但应该好理解)。
如果在上面代码行的下方增添一行
zhangSan=new People(160,150);
此时的“张三”指代的就并非之前那个一米八的瘦小伙了,而是取消了原本的指向后指向了新建的对象,“张三”矮了也胖了, 原本的瘦小伙已经成为了没有“名字”的可怜人,在合适的时机会被自动销毁。 (残忍) 而上述的两个对象产生在语句如在方法中,它们产生的对象都会储存在堆中,而并非与引用一样储存在栈内。
对象初始化与传参
基础数据类型传参:
基础数据类型的在为方法传参时传递的只是一个值,并非传递本身,方法中形参的修改不改变原值。
在show方法中的n为形参,即使执行了++操作,main中的原始值n并未改变。
类对象的传参:
类对象在参数传递时,类对象本身没有进行传递,也没有将值拷贝给形参,此处的形参代表也只是一个对象引用,传递参数时也只是对象引用传递给形参,使形参具有能“联络”对象的功能——成为对象的引用。
由于此时形参已经是对象的引用,所以方法中
对象引用的操作会使实际的对象数据改变。
对象的初始化:
对象在实例化类的过程中,在必要时需要进行数据的初始化,比如上述例子中的身高体重数据。在初始化时有多种方法,一种是自己为类进行初始化赋值,如下(未定义构造方法)。
这里在定义时便给予了数据初始值1。如果此时我们对为其定义的初始值不满意,此时我们需要利用构造方法为其初始化,构造方法的方法名与类名需要完全一致,并且方法不能有返回值。
用“new 类名(参数);”进行调用:
当我们如上不进行初始化定义,同时又没有自定义类的构造方法时,执行输出语句仍然有如下结果:
这里虽然没有人为的调用构造方法,但是系统会在装载类时配置类的默认构造方法,为提供初类中数据始值。综上可知,默认的构造方法会被定义好的初始值覆盖,而定义好的初始值会被调用构造方法覆盖。所以初始化的先后顺序(先后并非优先级)为—— 1. 系统默认构造 < 2.定义好的初始值 < 3.定义的构造方法。
非访问修饰符:
1.static:
静态修饰符,可修饰类方法与类变量,被修饰的方法与数据成为类的静态方法和变量。无static修饰的类方法与类变量并不是专属于类,而是在产生对象实例化的同时为对象产生属于对象的变量与方法,方法只能为对象调用。但是被static修饰后,这些变量与方法不再依托于实例化的对象,可以被类直接调用,也能为对象调用(但是一般情况不推荐后者)。所以在对对象抽象时某些属于类的专属公有且相同的属性或者方法可以用static修饰。main方法必修用static修饰,因为main方法不依托于对象。
这里的输出结果为类中的height初始值1:
同时由于static修饰的方法属于类,所以不能调用非static修饰的类变量,因为不同对象的类变量具有不可确定性。
2.final:
常修饰符,可修饰类、类方法、类变量和普通变量。修饰类时,类成为最终类,不可被继承。
此时子类student不可被继承,报错如下:
final在修饰类方法时,此时的类方法成为最终方法不可被子类所覆盖。
报错如下:
被修饰的类变量与普通变量成为常量,无法被改变值。
对象与数组
在Java语言中,数组也可视为一种类(一种特殊存在),我们不能在未进行创建对象时就规定数组的大小,数组名的声明类似于引用的声明。
float[100] arr;//此语句不可执行
//语句
float[] arr;
arr =new float[100];
//可以执行
因为数组需要视为类,此处的float数组为类的对象,所以不能直接在产生引用的语句中对类对象产生的数量进行定义,即使已经确定了指向的对象,也只能在创建对象的语句中体现对象数量,例如:
而对于类对象的数组,大致规则与上述基础数据类型一致,但是由于类对象也遵从不能在纯声明语句(无new创建对象语句)中进行创建,只能创建类的引用,所以在对象数组创建时,先创建数组引用,之后创建的数组对象中的对象是类对象的引用,需要再创建类对象使引用指向类对象从而实现对象的操作。
此时无法输出,因为数组内的对象引用并无具体指向。但是当数组是基础数据类型时,数组产生对象时会自动初始化内部数据,初始值为0,而引用数组则需再自行创建对象。如下: