Java基础
面向对象
类与对象
类,对象是面向对象最核心的概念。
类对应显示世界中的某一类事物,对象是某一类事物的具体实例。
类的构造方法(构造函数)
类再被创建对象的时候会被自动调用
类的属性
某一类事物的共有特性
操纵对象
c++中有指针和引用两个概念,c++中的指针概念就相当于Java中的引用概念。
c++的指针,java的引用,python中的变量,windows中的句柄都是同种东西,用来存储对象的地址。
c++中的指针含义:一个用来存储逻辑地址的内存,存储的数据是该对象的地址,不是该对象的属性或者值
回收对象所占用的内存
1.Java/python是自动回收内存的
python中有个叫GC(Gabage collector),自动监测
2.c++是手动回收
使用的是delete,比如说回收p,delete p,这个语句指的不是回收p指针,而是回收指针p指向的那个内存。
(1)忘了回收,内存泄漏
(2)回收多次,数据丢失
为什么c++会发生内存泄漏呢?
结构大概如上,当运行delete s的时候,只有shape会被回收,然而string这块内存没有被回收,如果有多个像name这样的属性,就会有很多内存没有被回收到,就会发生内存泄漏。
改进措施:
定义一个析构函数,析构函数填写如下:
当执行delete s的时候,析构函数会被自动调用,所以他会先执行delete name,从而先把string那块内存回收了,再回收shape,这样就不会发生内存泄漏了。
还要注意一个问题,如果上述中的属性指针对象没有初始化,他一开始是一个随机指针,如果就这样执行析构函数,不知道会把那个地方回收了,所以,严谨的写法是
特例
这里产生的对象分配在栈上面,由于main函数自身执行结束,他会把执行在main函数里的内存自动全部回收,所以分配在栈上面的对象会自动调用构造函数和析构函数。
new出的对象是会被分配到堆上面的,分配在堆上面的对象是要用到delete语句来把内存回收。python,java产生的所有对象都在堆上面。
成员方法(成员函数)
函数的调用过程:当java开始执行后,class是放在硬盘上,这个硬盘上有一个方法表,这个表记录了这个类所有的方法名,然后找到方法表中对应的方法名,然后在class这个内存中找到相应的代码来编译。
在Java中,无论new多少个实例,他new出来实例的内存中都不包含那个方法的,而是当调用方法的时候,他会在该class中的那个内存中的方法表找到相对应的方法,然后再在class内存中找到那段代码来执行。
绑定
通过方法名找到方法代码的过程佳作绑定
方法的绑定:对象里面没有方法,只会通过对象找到对应的类,然后找到对应的方法名,然后再找到对应的方法,这个过程叫作方法的绑定。
方法绑定有两种:
1.compile-time(编译器绑定)
编译器绑定又叫做是静态绑定。(构造方法,static,final,private)
对于Java来说就是一个java文件转为class文件的过程,如果能够找到对应方法名的代码,那这个过程就是编译器绑定。
2.run-time binding(dynamic binding)
当运行开始的时候,或者说的开始执行main方法的时候,再去找对应的方法,这个叫做动态绑定。
如何判断是静态绑定还是动态绑定?
只有一份代码对应方法名,没有歧义的,那么这就是静态绑定。
假如有一方法,有两份代码对应他,那么这就是动态绑定。
继承、重写、多态
继承:一类是另一类事物的特殊情况,有一些通用的属性可以定义在他的父类,而特色的属性则定义在他的子类里面。
重写(override、overwrite):与父类的方法名字相同,并对父类中的方法进行重新编写,当创建该子类的对象时,所调用的方法为子类重写的方法。
父类的引用可以指向子类的对象(多态的表现形式)
class Dog extends Animal{};
int main(){
Animal a = new Dog();
}
此时该实例所调用的方法为(所new的类),该题中new出来的是dog,所以调用的方法为子类dog的方法。不够有一点,该a实例只能访问Animal的属性,不能访问Dog的属性。
改进方法:
Dog d = (Dog) a;
把a的实例强制转换为Dog类型,所以 此时的d实例也可以访问Dog属性。
多态(Polymophyse)
有继承,有重写,父类的引用可以指向子类对象。
多态的意义:软件的可扩展性(extensibility)增强,添加新功能的时候不用修改大部分代码。