目录
- 快速注释
- 方法重载(overload)
- 可变个数参数的方法
- JVM内存模型
- 即对象的地址存在栈中,对象的值存在堆中
- 类实例化的对象也可以做形参(传递对象的地址)
- 包(package)
- 包的概念
- 引用关键字import
- JRE System Library
- 面向对象特征之一:封装和隐藏
- 访问修饰符
- 关键字this
- JavaBean
- 高级类的特性
- 面向对象特征之二:继承(extends)
- 类继承语法
- 继承的意义
- 类继承的规则
- 父子类与访问修饰符的关系
- 方法的重写(override)
- 定义
- 要求
- 快捷键
- 关键字super
- 调用父类的构造器
快速注释
快捷键:ctrl + /
方法重载(overload)
- 同名的方法,不同的参数(顺序/个数/类型)
- 必须在同一个类中
可变个数参数的方法
- 例:
public void printInfo(String... args){ //String... args / int... i
for(int i = 0;i < args.length;i++){ //迭代
System.out.println(args[i]);
}
}
- 使用这种方法,调用的时候没有参数也可以不填
JVM内存模型
JVM内存:
- 栈:基础数据类型(包括对象在堆中的地址)
- 堆:所有的对象(包括自定义的对象和字符串对象)
- 方法区:所有的class和static变量
即对象的地址存在栈中,对象的值存在堆中
类实例化的对象也可以做形参(传递对象的地址)
其实就是类似C里的结构体指针作形参:
传进来了地址,方法里变量的值改变,方法外对应的变量也会改变。
包(package)
包的概念
- 类似于文件夹,方便管理
- 不同包下允许两个class文件重名
- 用“.”来指明包的层级
- 包通常用小写单词,类名首字母通常大写
引用关键字import
- 举个栗子:包a里有类Person.java,包b下的包c里也有类Person.java,现在我要在包d的Test.java中调用包c中的Person.java,怎么辨别?
只需要使用import:
import b.c.Person;
Person p = new Person();
- 当然,这样也是可以的:
b.c.Person p = new b.c.Person();
- 或者可以简单粗暴地把包c下的所有文件都引用:
import b.c.*;
Person p = new Person();
- 如果使用同一个包下的类,import可以省略
JRE System Library
JDK中内置的包,包括java.lang、java.awt等等等等
面向对象特征之一:封装和隐藏
把类的属性开放出来,让调用者随意使用:
//class Person
public int age;
//class Test
Person p = new Person();
p.age = -100;
若是想不让调用者随意使用:做封装和隐藏处理:
//class Person
private int age;
public void setAge(int a){
if(a<=150 && a>=0){
System.out.println("年龄是"+a);
}else{
System.out.println("年龄输入错误啦,检查检查。")
}
}
//class Test
Person p = new Person();
p.setAge(18);
上面的方法与域访问器类似,都是封装特性的体现:
- 把属性设置声明为私有类型(关键字private)
- 通过编写public类型的setXxx()、getXxx()方法来设置属性和获取属性。
- (快捷键:右键-general setter and getter)
访问修饰符
下面这些关键字在Java中被称为权限修饰符,置于类的成员定义前,用来限制对象对该类成员的访问权限:
修饰符 | 类内部 | 同一个包 | 子类 | 其他地方 |
private | √ | |||
default | √ | √ | ||
protected | √ | √ | √ | |
public | √ | √ | √ | √ |
(不加修饰符,系统默认为default类型)
需要注意的地方:
- 对于class的权限修饰,只能使用public或default(即缺省)
- 同个文件中可包含多个类,但只能出现一个public类,其他类只能是缺省类
关键字this
观察下面是如何实现区分同名的形参和成员变量的:
public class Person{
public Person(int age,int name){
this.age = age;
this.name = name;
}
public int age;
public String name;
public void setName(String name){
this.name = name;
}
}
没错,就是用了this
!字面意思,this表示类对象本身。
- 合理使用
this
能增强代码的阅读性噢。 - 需要注意的是,this不能在static修饰的方法里使用。(具体原因问百度)
-
this
可以调用成员变量,也可以调用方法。 -
this
还可以用来调用构造方法:
this();
//等同于调用构造方法 public Person(){}
使用this()必须放在构造器的首行,且使用this调用本类其他的构造器,保证至少有一个构造器是不用this的(也就是构造器不能自己调用自己)。
JavaBean
JavaBean是一种Java语言协程的可重用组件,是指符合如下标准的Java类:
- 类是公共的(public)
- 有一个无参的公共的构造器
- 有私有的属性(private),且有对应的get、set方法
高级类的特性
面向对象特征之二:继承(extends)
类继承语法
public class PersonChild extends Person(){
System.out.println(age);
}
子类通过继承(关键字extends)的方式实现继承父类的方法和属性。
继承的意义
当多个类存在相同属性和行为时(子类),将这些内容抽取到单独一个类(父类)中,那么多个类无需再定义这些属性和行为,只要继承那个类即可。
- 提高了代码的复用性
- 继承的出现让类与类之间产生了关系,提供了多态的前提
- 继承的前提是要注重代码的逻辑性哦(不要仅为了获取其他类中某个功能而去继承)
- 概括来说:子类不是父类的子集,而是对父类的扩展
类继承的规则
- 子类不能直接访问父类中私有的(private)成员变量和方法
- Java只支持单继承,即一个子类只能有一个父类
- Java支持多层继承,即一个子类同时也是其他类的父类
- 子类并不会继承父类的构造器,子类的构造器必须通过关键字super调用父类的构造器
父子类与访问修饰符的关系
上面我们学了访问修饰符的访问权限范围:
修饰符 | 同一个类 | 同一个包 | 子类 | 其他地方 |
private | √ | |||
default | √ | √ | ||
protected | √ | √ | √ | |
public | √ | √ | √ | √ |
注:同一个包指的是同层的文件,包中的包不在同层文件的范围内。
上表表明:
- 如果父类和子类在同一个包下,那么对于父类的成员,只要不是 private,都可以使用;
- 如果不在同一个包下,子类只能使用父类中 protected 和 public 类的成员。
方法的重写(override)
定义
定义:在子类中可以根据需要对从父类继承来的方法进行改造,也称方法的重置、覆盖。在程序执行时,子类的方法将覆盖父类的方法。
要求
- 重写方法必须要和被重写方法具有相同的方法名称、参数列表和返回值类型(即方法体外不允许改动)只重新编写方法体内的代码
- 重写方法不能使用比被重写方法更严格的访问权限
- 重写和被重写的方法同时为static或非static
快捷键
快捷键:alt + / 提示补全
关键字super
super是Java中调用父类的指定操作的关键字:
- 父类的属性
- 父类的方法
- 父类的构造器
需要注意的是:
- 子父类出现同名成员时可用super进行区分;
- super的追溯不仅限于直接父类(多层继承追溯);
- super和this的用法相像,this代表本类对象的引用,super代表父类的内存空间的标识。
调用父类的构造器
注意:
- 子类中所有的构造器默认都会访问父类中空参数的构造器
- 当父类中没有空参数的构造器时,子类的构造器必须通过this或者super语句指定调用本类或者父类中相应的构造器,且必须放在构造器的第一行
- 即如果子类构造器没有显式调用父类或本类的构造器,且父类中又没有无参的构造器,则编译出错