/**
* java文件的执行
*/
Jdk是什么?
Java development kit java开发工具包
Jdk包括:
Jre(java运行环境)、
一堆java工具(java编译器javac.exe java解释执行器java.exe)、
java基础类库(3600多)常用类150多个
安装了JDK就没必要单独装JRE了。JDK可以理解为开发环境,JRE可以理解为运行环境。
安装后需要配置环境变量。
/**
* java文件的执行基本数据类型
*/
字符类型:char(字节数:2)
布尔类型:boolean (字节数:1/8)
整数类型:byte (字节数:2)
short(字节数:2)
int (字节数:4)
long (字节数:8)
浮点类型:float(字节数:4)
double(字节数:8)
/**
* 四种访问级别的访问范围
*/
/**
* 重写与重载
*/
重载是在同一个类中的,根据函数入参进行区分。方法名要相同,返回值可相同可不同。
重写对应多态,子类继承父类时,可以对其方法进行重写。
java不支持一个子类继承多个父类,C++是支持的。
/**
* static与final
*/
static意味着静态的,需要理解静态变量、静态代码块、静态方法。
静态变量只在类加载时分配一次内存,不需实例化对象即可使用。
静态代码块只在类加载时执行一次,如有多个,依次执行。
静态方法在类加载时分配内存,不需实例化对象即可使用。
final意味着值不可改变,需要理解final变量、final方法、final类。
final变量意味着常量,定义时就需要初始化。
final方法意味着不允许子类对其进行重写,编译器遇到final方法时,会转入内联inline机制,提高执行效率。
final类意味着不能被继承,不允许其有子类。
/**
* 值传递与引用传递
*/
值传递:传值,传对象的实际值
应用传递:传址,传对象的地址
要理解清楚这两个问题,首先要理解值和址的概念。
以我们写代码中最常见的语句为例:
StringBuffer str = new StringBuffer("Hello world!");
这个语句可以分为三部分:
1、在堆中开辟了一块内存,用于存放"Hello world!"。(new出来的,static声明的对象在堆中开辟空间)
2、在栈中开辟了一个int长度的空间,用于存放地址(指针)str。
3、将"Hello world!"的地址赋值给str。
当我们写如下语句"if(str2 == str)"时,只是判断两个指针的值(也就是对象的地址)是否相等,并不是判断被指向的对象是否内容相同。然而如果两个对象的地址完全相同,他们本身就是一个对象。但两个内容相同的对象,地址未必相同。这点在判等时必须考虑到。
当我们传址时,在函数内部对这个地址指向的对象进行修改的话,函数结束后,这个对象确实是被修改了。
总结一下:应用传递其实可以看做是址传递的一种,因为地址实际上也是一个int型的数。特别的是,在函数中修改这个指针指向的对象,函数结束后,对象也就被修改了。
/**
* 子类与父类
*/
遵循这样一个原则:子类的引用,不能指向父类的对象。父类的引用,可以指向子类的对象,但只能调用子类继承父类的那些方法。
例如:
父类:
public class Fulei {
public void eat(){
System.out.println("Fulei eat");
}
}
子类:
public class Zilei extends Fulei{
public void eat(){
System.out.println("Zilei eat");
}
public void play(){
System.out.println("Zilei play");
}
}
测试类:
public class ZileiFulei {
/**
* @param args
*/
public static void main(String[] args) {
//test1
Fulei fulei = new Fulei();
fulei.eat();
//test2
Zilei zilei = new Zilei();
zilei.eat();
zilei.play();
//test3
Fulei testFulei = new Zilei();
testFulei.eat();
//test4
Fulei testFulei2 = new Zilei();
Zilei testZilei2 = (Zilei) testFulei2;
testZilei2.eat();
testZilei2.play();
//test5
Zilei testZilei = (Zilei) new Fulei();
testZilei.eat();
testZilei.play();
}
}
分析:
子类的功能可以被父类的方法或引用变量调用,这叫向后兼容,可以提高程序的可扩充性和可维护性。
test1中定义父类引用指向父类对象,可以调用父类所有方法。
test2中定义子类引用指向子类对象,可以调用子类所有方法。
test3中定义父类引用指向子类对象,可以调用子类继承父类的方法。
test4中定义父类引用指向子类对象,又定义子类引用指向父类引用,相当于定义子类引用指向子类对象,可以调用子类所有方法。
test5中定义子类引用指向父类对象,不允许。
/**
* 抽象类abstract
*/
抽象类用以解决父类的不确定性问题。
用abstract修饰的类叫抽象类。
用abstract修饰的方法叫抽象方法。
实际使用中,我们更多的使用了接口来实现抽象的概念。因为在java中不支持多重继承,一个子类只能继承一个父类。因此当需要已有子类增加方法时,不得不修改父类。
用接口可以避免这个问题,因为java支持方法实现多个接口。这样如果要给类增加方法,可以新增一个接口。
当父类为抽象类时,子类需要实现父类中所有的抽象方法。
关于抽象类,有这样几个注意点:
1、抽象类不能被实例化,即不能定义实例化类的对象。
2、抽象类中可以没有抽象方法。
3、一旦方法声明为abstract类型的,即抽象的,则类必须声明为abstract的。
4、抽象方法不能有主体,即不能有{}。
/**
* 接口
*/
当一个类实现一个接口时,要求实现接口中的所有方法。
接口中的变量,默认是static final 类型的。
接口不能继承类,但是可以继承接口。