面向对象的三大特性:封装、继承、多态
前两个很好理解,重点是多态。java中多态分为两种,一种是函数的重载,另一种是子类的重写。这一点和C++中是相同的。
2、this指针this指针在C++中有如下两个作用
但是在Java中由于没有指针的概念,所以第二个不能用,只有第一个作用。
3、构造函数(同C++)1)构造函数的3个特点
- 没有返回值也不写void
- 函数名与类名相同
- 可以重载
2)一旦自己写了构造函数,编译器就不提供默认的构造函数了。
在下面的例子中,这种情况会报错。
文件(一)Hello.java
public class Hello {
String morning;
Hello(String morning){
this.morning=morning;
}
}
文件(二)主类.java
由于我们自己写了一个构造函数,编译器不提供默认构造函数了,那么这个时候再new Hello(),参数为空,就会报错。避免的措施就是,我们再自己写一个默认的构造函数(同C++)。
文件(一)Hello.java
4、由于垃圾回收机制的存在,java没有析构函数 5、对象的内存模型注意对象的引用和对象的实体这两个概念。
5.1 声明对象后的内存模型假如我们有一个Person类,有String name,int age,double height3个成员变量。
Person p;
这时p是一个空对象(说是空引用更好理解一些),它的值默认为null。
5.2 创建对象后的内存模型p = new Person();
1)为name、age、height各个变量分配内存
2)为name、age、height各个变量进行初始化。(如果有构造函数按照构造函数进行,没有就默认用惰性值还记得吗)
3)计算出一个称为引用(可以看做地址)的值,把该引用赋值给p。
5.3 垃圾回收机制 —— 自动回收堆区new出来的在C++中,我们用一个指针去接收new出来的值,例如
int *p = new int(10);
所以java中的引用可以看作指针或地址
对象的引用存在栈区中(Person p和成员变量一样存放在栈区),对象的实体存放在堆区(new出来的都存放在堆区)。
在C++中,由编译器自动管理栈区。由程序员手动管理堆区(new 和 delete)。
java的垃圾回收机制自动收走堆区中不再被引用指向的实体,不需要程序员手动管理了。
下面用内存模型解释一下什么叫“不再被引用指向的实体”
Person p1 = new Person("jj",18,162.5); Person p2 = new Person("hh",25,174.0);p2 = p1;
上图中右边被框起来的就是不再被引用指向的实体。
总结起来就一句话,java自动管理堆区和栈区。
5.5 java中引用和C++中引用的区别我认为java中的引用和C++中的引用不能记成一个概念,java中的引用更多的是“地址”的意思。
- 在C++中,只需要记住一句话“引用是变量的别名”,基本数据类型可以有引用int &m=a,对象也可以有引用。在java中,分为引用数据类型和基本数据类型,从命名就能看出,只有引用数据类型能使用引用,基本数据类型不能。
- 在C++中,引用的本质是“指针常量”,既然是常量那么就不能改变,也就是说不能再给引用赋第二个值。
int &m=a; m=b; //错误!
在java中,引用是可以被重复赋值的(所以java中的引用理解成“地址”更好)。
Person p = new Person("jj");
p = new Person("hh"); //这是可以的!
6、类与程序的基本结构
1)最好是源文件都保存在相同的目录中。
2)如果非要不放在相同目录中,那么编译好的字节码文件和主类的字节码文件必须放在相同目录中
3)如果主类所在的源文件和其他源文件在同一目录,那么可以只编译主类所在的源文件,运行时会自动编译其他源文件。
7、参数传值 7.1 传基本数据类型可以将低级别的传给高级别。例如:
void add(double a,double b){
}
可以传递double型和比double型级别更低的数据类型,比如:
add(10, 12);7.2 传引用数据类型
“当多个引用(地址)指向同一实体时,所有的引用(地址)都能操纵这个实体”。
在下面这段程序中,battery和nanfu这两个引用一个是形参一个是实参,指向同一个实体,都可以操纵这个实体。
7.3 可变参数
1)语法
参数个数可以灵活变化。
void add(int x,int ... y)
但是下面这种是不对的,可变参数必须放在最后!
void add(int ... x,int y)
这一点和C++对于默认参数的规定有异曲同工之处,但是需要注意的是java不允许存在默认参数 。
2)提供x.length
public int add(int ...x){
int sum=0;
for(int i=0;i
3) 提供增强的for语句
public int add(int ...x){
int sum=0;
for(for i:x){
sum=sum+i;
}
return sum;
}
8、对象的组合—— 类A使用类B的对象作为其成员变量。
我们直接借助一个例子去看内存模型的变化。
Circel.java
Cicular(圆锥).java
主类.java
我们主要是看其中【代码4】【代码5】【代码6】之后内存模型的变化。【代码4】之后,
【代码5】之后,
【代码6】之后,
9、类的关联关系和依赖关系
其实这两个关系在上面的例子中已经涉及到了。
1)类的关联关系就是类的组合,即刚刚说过的类A使用类B的对象作为其成员变量。
2)类的依赖关系,A类中某个方法的参数是B类的对象(南孚电池那个例子),或者,A类中某个方法的返回值是B类的对象。
10、 方法重载
和C++的记忆点相同:
- 函数名相同,参数不同
- 仅返回值类型不同 不是重载
仅有一点不同,因为java不允许形参默认参数,所以不会出现C++中的歧义
void func(int a, int b=10){
}
void func(int a){
}
func(10) //编译器分不清到底应该调用哪个勒?
但是你以为这样就不会存在歧义了吗?
void func(double m, int n){
}
void func(int m, double n){
}
func(10,10); //前面讲过,可以向double传递int类型的值。所以现在编译器分辨不出应该用哪个方法了
这种歧义只能由程序员去避免。



