一、用于定义访问权限修饰符的关键字(private、protected、public)
注意:java访问控制是停留在编译层的,不会在.class文件中留下任何痕迹,只在编译时候进行访问控制的检查。
1、private
只能被自己(本类)访问和修改。
- 利用private 实现封装,但是使用private关键字只是实现封装的第一步。
- 被private修饰的是能被本类访问,不允许外部类访问。
- 类的内部操作对外不可见,对象不能直接操作属性。
- 要访问私有属性:
setter方法:主要用于对属性内容的设置和修改。
getter方法:主要用于对属性的取得。
2、protected
自身、子类、同一个包下中的类可以访问;主要作用是保护子类的。
3、public
可以被所有其他类所访问,往往用于对外的情况,也就是对象或者类对外的一种接口形式。
- public关键字声明类时必须与java文件名保持一致;一个java文件中只有一个public类,编译后产生一个与java文件名相应的.class文件;一个java文件中可以有多个不使用public修饰的类。编译后产生多个与之对应的.class文件。
二、用于定义类、函数、变量、修饰符的关键字(static、finnal、abstract、synchronized)
1、static(和对象进行解绑)
作用:
1、修饰属性: 共享属性,静态属性、又称类属性;保存在全局数据区的内存之中,所有数据都可以进行数据区的访问。
- 访问静态属性:类名.属性名
- 静态属性是放在全局变量的数据内存中,所有对象都可以对该数据进行访问。
- 所有非静态属性必须在对象实例化之后使用,静态属性不受对象实例化的控制。
//非静态属性
class Person{
int age;
String name;
String country = "中国";
public void getInformation(){
System.out.println("姓名:" + name + ",年龄:" + age + ",国籍:"
+ country);
}
}
public class Test {
public static void main() {
Person per1 = new Person();
Person per2 = new Person();
per1.age = 10;
per1.name = "张三";
per1.getInformation();
per2.age = 20;
per2.name = "李四";
per2.getInformation();
}
}
上述代码对应的内存模型:
//静态属性
static String = "中国";
//修改country属性,所有对象同步此属性
内存模型:
2、修饰方法:(与对象进行解绑)
- 目的:某些方法不希望受到对象的控制,可以在没有对象实例化的时候执行。
- 访问静态方法:类名.方法
- 所有的static方法不可以调用非static属性或方法。
- 所有的非static 方法可以调用static方法或属性。
2、finnal
- 修饰变量:变量只能被赋值一次,必须在声明时就赋值。
- 修饰方法:方法不能被子类所覆写,(String类就是使用finnal定义)
- 类不能被继承,即没有子类。该类的所有方法默认都加上finnal修饰。
abstract 修饰方法 、修饰类
- 修饰类:抽象类中有抽象方法,抽象方法无方法体(无具体实现),所以抽象类不能直接产生实例化对象。
- 修饰方法:抽象方法,无方法体。
public abstract void pritf(); //正确
public abstract void pritf(){} //错误
抽象类使用原则:
- 所有抽象类必须有子类,所以抽象类不能被finnal修饰。
- 抽象类的子类必须覆写抽象类的所有抽象方法。所以抽象方法不能使用private定义。
- 抽象类的对象可以通过对象多态性利用子类为其实例化。实例化子类时一定先调用父类的构造方法,如果父类中没有无参构造方法,则子类构造必须使用super明确指出使用父类哪个构造方法。
- private与abstract不能同时使用。
- 即使抽象类中不定义任何抽象方法,抽象类也不能直接产生实例化对象。
4、synchronized
(加锁)
待填
三、 用于定义类与类之间关系的关键字(extends、implements)
1、extends(继承) 单继承
主要作用:在已有的基础上进行功能扩充;使代码重用
例如:people为父类则学生、医生等各是是一个子类,不同的学生都有姓名、年龄、等相同的特征;学校可能不同;不同的医生医院不同。
- 子类在进行实例化前一定先实例化父类对象,默认先调用父类构造方法再调用子类构造方法对子类进行子类对象初始化。
注意1:实际上在子类的构造方法中,相当于隐含了一个语句 super();
注意2:如果父类中没有提供无参构造,此时必须使用super()明确指明要调用的父类构造方法。 - 不允许多重继承,只允许多层继承。
class Person{
private String name;
private int age;
public Person() {
System.out.println("这是父类无参的构造方法");
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
class Student extends Person{
public Student()
{ super(); //父类构造方法无参时可以不写
System.out.println("这是子类的构造方法");
}
String school;
public String getSchool() {
return school;
}
public void setSchool(String school) {
this.school = school;
}
}
public class Test {
public static void main(String[] args) {
Student stu1 = new Student();
stu1.setSchool("阳光中学");
stu1.setName("花花");
stu1.setAge(16);
System.out.println("学校:" + stu1.getSchool() + " 姓名:" + stu1.getName() + " 年龄:" + stu1.getAge());
}
}
覆写:
- 方法的覆写:自类定义了与父类方法名称、参数类型几个数完全相同的方法。但是覆写不能够拥有比父类更严格的访问控制权限。(private < defalt < public )
覆写中注意的两点:
- 当前使用的对象是通过哪个类new的
- 当调用某个方法,如果该方法已经被子类所覆写了,那么调用的一定是被覆写过的方法。
覆写和重载的区别:
2、 implements(子类实现接口,多继承)
- 抽象类与普通方法(一般继承)最大的特点是约定了子类的实现要求;但是抽象类中存在单继承局限。使用接口既可以约定子类实现要求并可以避免单继承的局限。
- 接口定义:接口就是抽象方法和全局常量的集合。
interface IMessage{![在这里插入图片描述]()
public static finnal String MSG = "I am a biter"; //全局变量
public abstract void print(); //抽象方法
//void print(); 也可以省略掉abstract
}
class Message implements IMessage{
public void print(){
System.out.println(IMessage.MSG);
}
}
接口使用限制:
- 接口中只允许public权限。(属性和方法)
- 当一个子类即需要实现接口又需要继承抽象类时,先使用extends继承抽象类,再使用implements实现多个接口。
- 一个抽象类可以使用implements实现多个接口,但是接口不能继承抽象类。
抽象类与接口的区别:
四、用于定义建立实例及引用实例,判断实例的关键字(new、this、super、instanceof)
1、new(开辟内存空间)
Person per = new Person();
(1)对象内存分析:
- 栈内存:存放局部变量(包含包含编译期间可知的各种基本数据类型、对象的引用——即堆内存的地址)。
- 堆内存:保存的是真正的数据,即对象的属性。
class Person{
String name;
int age;
public Person(String name,int age){
this.age = age;
this.name = name;
}
public class Test{
public static void main![在这里插入图片描述]()(String[] args){
Person per = new Person("张三",18);
}
}
}
对象(引用数据类型)必须在实例化后调用,否则会产生NullPointException(运行时错误),编译时不会出错。
(2)引用传递分析
引用传递的本质:一块堆内存可以被多个栈内存所指向。
2、this
(1)this调用本类属性
class Person{
private String name;
int age;
public Person(String name,int age){
this.name = name;
this.age = age;
}
}
(2)this调用本类方法
- 调用普通方法(this.方法名称)
class Person{
private String name;
int age;
public Person(String name,int age){
this.name = name;
this.age = age;
this.print(); //不加this也可以,但是加上this可以区分方法的来源
}
public void print(){
System.out.println("*********");
}
}
- 调用构造方法 ( this(参数))
注意: this调用构造方法的语句必须在构造方法的首行。
class Person{
public Person(){
System.out.println("产生一个新的Person对象");
}
public person(String name){
this(); //调用本类无参构造
this.name = name;
}
public Person(String name,int age){
this(name);
this.age = age;
}
}
(3)this表示当前对象
只要对象调用了本类中方法,这个this就表示当前执行的对象
class Person{
public void print(){
System.out.println("[PRINT]⽅法:"+this);
}
}
public class Test{
public static void main(String[] args) {
Person p1 = new Person();
System.out.println("[MAIN]⽅法:"+p1);
p1.print();
System.out.println("=================");
Person p2 = new Person();
System.out.println("[MAIN]⽅法:"+p2);
p2.print();
}
}
3、super
(1)使用super调用父类的同名方法
class Person{
public void print(){
System.out.println("1.I am father");
}
}
class Student extends Person{
public void print(){
super.print();
System.out.println("2.I am child");
}
}
public class Test{
public static void main(String[] args) {
new Student().print();
}
}
使用super调用父类属性
public String info = "爸爸!";
}
class Student extends Person{
public String info = "⼉⼦!" ;
public void print(){
//不找本类中的属性
System.out.println(super.info);
System.out.println(this.info);
}
}
public class Test{
public static void main(String[] args) {
new Student().print();
}
}
this和super的区别:
4、 instanceof(Java的一个二元操作符)
作用:判断左边对象是否为右边类的实例,返回boolean类型数据。
per instanceof student per引用是否能指向student类引用的对象
五、用于处理异常的关键字(try、catch、throw、throws)
1、 try
try{
//出现异常的情况
}catch(异常类型 异常对象){
//
}
finally{
//无论是否存在异常,都会执行到finnally
}
2、catch
捕获异常
3、finally
public static void main(String[] args) {
System.out.println(func());
}
public static int func() {
try {
return 10;
} finally {
return 20;
}
}
// 执行结果
20
finally注意事项: finally执行的时机是方法返回之前(try或着catch中如果有return会在这个return之前执行finally)。但是如果finally中也存在return语句,那么就会执行finally中的return,而不会执行try中的return。(不建议在finally中写return)
4、throw
抛出异常
if(y == 0){
throw new ArithmeticException("抛出除 0 异常");
}
4、throws
将异常显示标注在方法定义的位置
受查异常必须用throws显示处理。
派生于Error类和RuntimeException类的所有异常类称为非受查异常。所有其他类为受查异常。
六、用于包的关键字(package、import)
为了更好的组织类,防止命名冲突,Java提供了包机制。
1、package
作用:
- 把功能相似或相关的类或接口组织在同一个包中,方便类的查找和使用。
- 和文件一样,包也采用了属性目录的存储方式。同一个包中的类名字是不同的,不同包中的类名字可以相同。当调用不同两个包中相同类名时,加上包名区别。
- 包也限定了访问权限,拥有包访问权限的类才能访问某个包中的类。
package pakg1[.pakg2.[.pakg3.....]];
例如,一个Person.java文件的内容如下:
package net.java.util;
public class Person{
...
}
它的路径是net/java/util/Person.java这样保存的。package的作用是吧不同的java程序分类保存,更方便的被其他java程序调用。
包的声明必须放在源文件的开头。
2、import
为了能够使用包中的某一个成员,需要利用import语句将包导入。
import语句放在package语句之后,所有类定义之前。
import package1[.package2...].(classname|*)
//*为通配符
七、用于数据类型的关键字
1、整形变量(int)
4个字节 -2^31 -> 2^31-1
2、长整型变量(long)
8个字节 -2^63 -> 2^63-1
3、短整型变量(short)
2个字节 -2^15 -> 2^15-1
4、双精度浮点型变量(double)
8个字节 不能单纯的用2^n表示数据范围
5、单精度浮点型变量(float)
4个字节
6、字符型变量(char)
2个字节
7、字节类型变量(byte)
1个字节 -128 -> +127
8、布尔类型变量(boolean)
默认值:false
boolean 类型有些JVM的实现是占1个字节,有些是占1个比特位。
package、import内容参考菜鸟教程