Java 学习笔记(4)——面向对象
现在一般的语言都支持面向对象,而java更是将其做到很过分的地步,java是强制使用面向对象的写法,简单的写一个Hello Word都必须使用面向对象,这也是当初我很反感它的一点,当然现在也是很不喜欢它这一点。但是不得不说它设计的很优秀也很流行。
面向对象
面向对象一般是将一些独立有相似功能的模块封装起来组成一个类,然后调用者不必关注实现细节而只需要关注调用某个类方法即可。面向对象简化了程序设计。与之相对应的是面向过程,而C就是典型的面向过程的程序设计语言。
面向对象一般有3种特性:封装、继承、多态。这次主要讲述的是java中的封装型。
在java中类的定义与C++中类的定义类似,只是在java中每定义一个方法或者成员变量都需要在前面添加一个访问的权限修饰符,比如下面的定义
class Student {
private String name;
private int age;
public Student(){
}
public Student(String name, int age){
this.name = name;
this.age = age;
}
public int getAge(){
return this.age;
}
public String getName(){
return this.name;
}
public void setAge(int age){
this.age = age;
}
public void setName(String name){
this.name = name;
}
}
而C++中只需要将具有相同访问属性的放到一块,用一次修饰符即可。比如上面java代码对应的C++代码如下:
class Student {
private:
string name;
int age;
public:
Student(){
}
Student(string name, int age){
this->name = name;
this->age = age;
}
int getAge(){
return this->age;
}
String getName(){
return this->name;
}
void setAge(int age){
this->age = age;
}
void setName(String name){
this->name = name;
}
}
访问权限
在C++中类中的成员如果不给访问权限,默认是private, 而java中默认的访问权限是friendly,但是这个friendly在java中并不是关键字,而且java中的public、private、protected 都必须明确指定,在java中这些关键字对应的访问权限如下:
访问权限 | 当前类 | 同一个package | 子孙类 | 其他package |
---|---|---|---|---|
public | yes | yes | yes | yes |
protected | yes | yes | yes | no |
firendly | yes | yes | no | no |
private | yes | no | no | no |
从上一个表中可以看到public 对于类成员的访问完全没有限制、而protected仅仅保护类成员不被其他包访问,默认的friendly只允许同一个包或者同一个类的成员访问,最后的private仅允许同一个类的成员访问,它们的访问权限是递增的,也就是public > protected > friendly > private
封装性
面向对象的封装性就体现在仅仅允许通过类方法访问类成员。这有助于保护类成员不被其他代码随意的篡改,而且如果类成员在进行修改时如果会涉及到其他变化,我们只需要在get/set方法中控制即可,不需要外部使用人员了解这个细节。
假设现在有一个教务系统,里面需要存储学生的信息,那么如果不采用封装的方式而直接在类代码外进行访问的话,而且成员被访问的位置较多,一旦发现数据库中存储的数据发生错误,那么将无法确定是在哪给定了错误的值,而且要对输入值进行判断的时候,每个被访问的位置都要添加这些判断的代码,修改量较大,而且无法保证每个位置都正常修改了。如果后续业务逻辑修改,那么这些工作又得重新做一遍。如果我们将成员变量使用set和get方法进行封装,查看数据错误的问题只需要关注get/set方法,而且业务逻辑变更时只需要修改get/set方法。这点体现了封装性对数据的保护作用。
在假设这里我们采用多线程的方式来访问数据,那么为了保护数据,就需要添加相应的同步代码,如果直接访问,那么每当访问一次数据,就需要添加保护代码。这样就为使用人员添加了不必要的麻烦,如果我们将这些进行封装,然后告诉使用人员,这个类是线程安全的,那么使用人员直接调用而不用管其中的细节,后续如果我们换一种同步的方式,也不影响其他人的使用。
this关键字
C++中this关键字就是一个指针,通过eax寄存器传入到类的成员函数中,在成员函数中,通过this + 偏移地址来定位类中所有成员。而java中this除了能像c++中那样用于表示访问类成员外,还有另外两个作用
- 使用this表示调用类其他的构造函数,比如下面的代码:
class Student {
private String name;
private int age;
public Student(){
}
public Student(String name){
this(); //调用无参构造
this.name = name;
}
public Student(String name, int age){
this(name); // 调用有一个参数的构造方法
this.age = age;
}
public int getAge(){
return this.age;
}
public String getName(){
return this.name;
}
public void setAge(int age){
this.age = age;
}
public void setName(String name){
this.name = name;
}
}
- 用来表示类的对象,其实这个作用与C++中this指针的作用相同,而且二者本质也一样,只是Java中不能直接访问内存地址,所以这里与C++有些许不同。
class Student {
private String name;
private int age;
public Student(){
}
public Student(String name){
this(); //调用无参构造
this.name = name;
}
public Student(String name, int age){
this(name); // 调用有一个参数的构造方法
this.age = age;
}
public int getAge(){
return this.age;
}
public String getName(){
return this.name;
}
public void setAge(int age){
this.age = age;
}
public void setName(String name){
this.name = name;
}
public boolean compare(Student stu){
return this == stu; //这里简单实用二者的地址进行比较
}
}
构造函数与析构函数
java中的构造函数与C++中的相同。是在new对象的时候调用的函数。注意这里只是说它在new的时候调用的函数,并不是在使用类的时候第一次调用的函数。
Java 中的构造方法必须与该类具有相同的名字,并且没有方法的返回类型。每个类至少有一个构造方法。如果不写一个构造方法,Java 编程语言将提供一个默认的,该构造方法没有参数,而且方法体为空。如果一个类中已经定义了构造方法则系统不再提供默认的构造方法。
java中不能直接访问内存,虽然它的类都是new出来的,但是资源的回收由垃圾回收机制来完成,那么它有析构函数吗?答案是肯定的,java中也是有析构函数的。在C++中进行栈资源回收或者手工调用delete的时候才会进行析构函数的调用。而在java中,当垃圾回收器将要释放无用对象的内存时,先调用该对象的finalize()方法。这个finalize方法就是类的析构函数,这个方法是由Object这个基类提供的一个方法,Object子类可以选择重写它或者就用默认的。这个方法严格上应该是一个接口函数,与C++的析构并不相同。
Java 虚拟机的垃圾回收操作对程序完全是透明的,因此程序无法预料某个无用对象的finalize()方法何时被调用。
类的静态代码块
上面说构造函数并不是使用类时第一个调用的函数,第一个调用的函数应该是静态代码块(这个代码块应该不能被称之为函数)。静态代码块是第一次使用类的时候被调用,而且仅仅只调用这一次。它的定义如下:
class Student{
staic {
System.out.println("调用静态代码块");
}
}
Java 学习笔记(4)——面向对象的更多相关文章
- Java学习笔记之---面向对象
Java学习笔记之---面向对象 (一)封装 (1)封装的优点 良好的封装能够减少耦合. 类内部的结构可以自由修改. 可以对成员变量进行更精确的控制. 隐藏信息,实现细节. (2)实现封装的步骤 1. ...
- Java学习笔记之面向对象、static关键字
一周Java学习总结 今天就总结理清一下关于面向对象和面向过程的程序设计的一些不同特点,以及讲下static关键字. 面向对象 现在接触的Java是面向对象的,现在的程序开发几乎都是以面向对象为基础的 ...
- 【原】Java学习笔记019 - 面向对象
package cn.temptation; public class Sample01 { public static void main(String[] args) { // 仔细想一想,Ani ...
- Java学习笔记--关于面向对象的思考
1.不可改变的类生成对象以及变量的范围 2. 关键词this的使用 3.用类抽象的思想制作软件 4.通过关系模型建立类 5.使用面向对象的范例来设计程序,遵循类设计指导. 已经学习了:怎么定义类已经创 ...
- 疯狂java学习笔记之面向对象(一) - 定义类、方法、构造器
Java面向对象 1.定义类 2.创建对象.调用方法 类和对象: 某一类对象的概念定义. 比如:人类 - 抽象出来的概念(不特指某个人) 对象 - 在类的概念下产生的一个实例,它就是一个对象了. ja ...
- java 学习笔记2 面向对象(上)
类和对象 类是某一批对象的抽象,可以把类理解成某种概念.对象是一个具体存在的实体.类和对象是面向对象的核心. 类定义的是多个实例的特征,类不是具体存在,实例才是具体存在. 定义类(class)的语法: ...
- 【原】Java学习笔记016 - 面向对象
package cn.temptation; public class Sample01 { public static void main(String[] args) { // this 关键字 ...
- 【原】Java学习笔记014 - 面向对象
package cn.temptation; public class Sample01 { public static void main(String[] args) { // 面向对象思想 // ...
- Java学习笔记之面向对象
面向对象概念 面向对象编程 &面向过程编程 面向对象:关心是谁来做 面向过程:关心的是怎么做 面向对象总结成一句话:就是分工与协作,干活的是对象 生活中: 对象 -----抽象-------- ...
随机推荐
- 【AtCoder Regular Contest 092】C.2D Plane 2N Points【匈牙利算法】
C.2D Plane 2N Points 题意:给定N个红点二维坐标N个蓝点二维坐标,如果红点横纵坐标都比蓝点小,那么它们能够构成一组.问最多能构成多少组. 题解:把满足要求的红蓝点连线,然后就是匈牙 ...
- Xcode 中的Bundle versions string, short 和 Bundle version 区别
Bundle version is the internal version number of your app. Short version string is the publically vi ...
- Vue知识点——vue数据深拷贝方法
背景 在vue页面传递数据的过程中,传递数据的引用地址并不会改变,所以当我们改变一些数据时,数据源 也会随之改变.可是有很多情景,我们改变传递的数据,并不需要源数据值发生变化,这时我们就需要对数据进行 ...
- 64位Linux编译C代码,crt1.o文件格式不对的问题
今天在某台64位LInux下编译一个简单的hello world的C程序,报错: /usr/lib/gcc/x86_64-redhat-linux/4.4.7/../../../crt1.o: cou ...
- Python两个字典键同值相加的几种方法
版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明.本文链接:https://blog.csdn.net/Jerry_1126/article/de ...
- 枚举类型的数据存入到map中
阅读更多 原文来自http://fokman.iteye.com/blog/1568905 public enum IdeasCMD { RESERVED(0), PING(1), PING_ACK( ...
- TensorFlow 池化层
在 TensorFlow 中使用池化层 在下面的练习中,你需要设定池化层的大小,strides,以及相应的 padding.你可以参考 tf.nn.max_pool().Padding 与卷积 pad ...
- @codeforces - 1106F@ Lunar New Year and a Recursive Sequence
目录 @description@ @solution@ @accepted code@ @details@ @description@ 定义递推数列 f: (1)f[1] = f[2] = ... f ...
- 模板—Kruskal
int getf(int x){return (f[x]==x)?x:f[x]=getf(f[x]);} void hb(int x,int y){x=getf(x),y=getf(y),f[y]=x ...
- 支付宝防并发方案之"一锁二判三更新"
每年支付宝在双11和双12的活动中,都展示了绝佳的技术能力.这个能力不但体现在处理高TPS量的访问,更体现在几乎不会出错,不会出现重复支付的情况,那这个是怎么做到的呢? 诚然,为了实现在高并发下仍不会 ...