一、包和权限修饰符
1.什么是包?
包是一种划分类的层次和结构的封装形式,类似于文件管理系统中的文件夹,并且实际也是以文件夹为形式载体的
2.包的作用
- 对类文件进行分类管理。
- 给类文件提供多层名称空间。
3.包的一般规则及导包
(1)一般规则
- 建包语句必须在第一行;
- 一般在定义包名时,因为包的出现是为了区分重名的类。所以包名要尽量唯一。(可以使用url域名来进行包名称的定义,且域名要倒置,如 package com.windx.javabean;)
- 包的名称建议全部小写;
- 若生成的包不在当前目录下,最好要执行classpath,将包所在父目录定义到classpath变量中;
(2)导包
- 相同包下的类可以直接访问,不同包下的类必须导包,才可以使用!
- 当一个类中需要用到不同包中名称相同的不同类时,默认只能导入一个类,另一个类要带包名访问。【这种情况一定要注意不要导错了包!】
- 导包格式:import 包名.类名;
4.权限修饰符
由于包与权限修饰符有一定关,所以就在一起说
(1)分类及具体作用范围
权限修饰符:有四种作用范围由小到大
(private --> 缺省 --> protected --> public )
具体如下:
修饰符 | 同一 个类中 | 同一个包中其他类 | 不同包下的子类 | 不同包下的无关类 |
private | √ | – | – | – |
缺省 | √ | √ | – | – |
protected | √ | √ | √ | – |
public | √ | √ | √ | √ |
(2)如何使用权限修饰符?
- 成员变量一般私有。
- 方法一般公开
- 若只希望本类访问,则使用private
- 如果只希望本类,同一个包下的其他类和子类访问,使用protected修饰
二、final关键字和static关键字
1.final关键字
(1)基本解释
final 关键字是最终的意思,可以修饰(类、方法、变量)
(2)作用
(3)注意事项
- final修饰的变量一定要初始化
- final修饰的变量是基本类型:那么变量存储的数据值不能发生改变。
- final修饰的变量是引用类型:那么变量存储的地址值不能发生改变,但是地址指向的对象内容是可以发生变化的。
- (如修饰一个实例对象时,可以改变实例对象的属性,但是不能改变该对象名的地址指向)
2.static关键字
(1)基本解释
static方法一般称作静态方法,被其修饰的方法或变量不再需要使用对象进行访问,因此方便在没有创建对象的情况下来进行调用方法/使用变量。
(2)注意点
- static修饰的变量不需要初始化,会有默认赋值
- 由于静态方法/变量不依赖于任何对象就可以进行访问,因此它们没有this可以使用
- 静态方法中不能访问类的非静态成员变量和非静态成员方法,因为非静态成员方法/变量都是必须依赖具体的对象才能够被调用。
具体例子(下图红色为idea中提示错误语法):
下面是具体代码,大家也可以自己进行试验
public class Test2 {
private static String str1 = "windx";
private String str2 = "xlk";
private void print0(){
System.out.println("私有静态方法");
}
public Test2(){}
//非静态方法---可以调用静态的,也可以调用非静态的
public void print1(){
System.out.println(str1);
System.out.println(str2);
print0();
}
//静态方法---不可以使用非静态变量和非静态方法
public static void print2(){
System.out.println(str1);
System.out.println(str2);
print0();
}
}
其他static详细作用见笔者上一章博文
3.常量
(1)基本解释
常量 是使用了public static final修饰的成员变量,必须有初始化值,而且执行的过程中其值不能被改变。
(2)使用场景及规范
使用场景
由于其本质就是进行字面量的替换,即 在编译阶段会进行“宏替换”:把使用常量的地方全部替换成真实的字面量
所以常常使用在一些常用固定数值上,如
- JavaGUI很多程序的长宽设置
- 计算简单数学题时,确定π的近似值
- 一些常用字符串等等
使用规范
- 使用大写的英文字母,若有多个则用下划线连接,如 PASS_WORD
- 一般定义在类的开头位置
三、枚举
1.基本解释
简单说下注意事项,平时我用的不多
枚举是一种特殊的类型,大概也算引用类型吧,跟String性质差不多
2.枚举的使用
格式:
修饰符 enum 枚举名称{
第一行都是罗列枚举类实例的名称。
}
一般修饰符常常省略,例子如下:
enum Season{
SPRING , SUMMER , AUTUMN , WINTER;
}
3.深入了解枚举
枚举的特征如下:
四、抽象类
1.基本解释
使用abstract关键字修饰类,这个类就是抽象类;修饰方法,这个方法就是抽象方法。
2.使用规范
格式:
3.注意事项
- 抽象方法只有方法签名,不能声明方法体。
- 一个类中如果定义了抽象方法,这个类必须声明成抽象类,否则报错。
- 抽象类不一定有抽象方法,但是有抽象方法一定是抽象类!
- 抽象类的作用就是提取公共部分,然后作为父类,让具体类来继承的
- 抽象类不可以创建实例对象,因为其构造器是私有的
- 有种跟final作对的感觉,hhh
五、面向对象三大特性之三 ---- 多态
1.什么是多态
多态指的是 对象可以有多种形态
2.多态的前提
- 有继承/实现关系;
- 有父类引用指向子类对象;
- 有方法重写(多态侧重行为多态)
3.类型转换(代码讲解)
public class Test {
public static class Animal{
private String name;
Animal(){
System.out.println("父类的空构造器");
}
Animal(String name){
this.name = name;
System.out.println("父类带参构造");
}
public void eat(){
System.out.println("吃东西");
}
public String getName() {
System.out.println("我是一只小动物,我的名字叫"+this.name);
return name;
}
public void setName(String name) {
this.name = name;
}
}
public static class Cat extends Animal{
private String name;
Cat(){
System.out.println("子类的空构造器");
}
Cat(String name){
this.name = name;
System.out.println("子类带参构造");
}
@Override
public void eat() {
// super.eat();
System.out.println("小猫吃鱼");
}
public void play(){
System.out.println("小猫玩逗猫棒");
}
@Override
public String getName() {
System.out.println("我是一只小猫,我的名字叫"+this.name);
return name;
}
}
public static void main(String[] args) {
Cat c1 = new Cat();
System.out.println("-------");
Animal c2 = new Cat("加菲"); //从子到父,自动类型转换
c2.eat(); //只可以调用父类有的方法,若子类有重写,则调用重写方法
c2.getName();
// c2.play(); //若是子类独有的方法,则无法调用
System.out.println("-------");
Animal c3 = new Animal(); //从父到子,强制类型转换
//强制转换原则----java中父类强制转换成子类的原则:父类型的引用指向的是哪个子类的实例,就能转换成哪个子类的引用。
c3.eat();
if (c3 instanceof Cat){
Cat c4 =(Cat)c3; //这里报错,说c3 is Null,奇怪
c4.eat();
c4.play();
}else {
System.out.println("c3不是Cat类的实例,所以不能强制转换");
}
Cat c5 = (Cat) c2; //本来c2是不能调用子类方法的,但是强转为Cat类后就可以了
c5.play();
c5.getName();
}
}
上述代码实现结果如下:
由此可见,在Java中有以下两种类型转换
- 自动类型转换(从子到父)
无法调用子类独有的方法和变量 - 强制类型转换(从父到子)
原则:父类型的引用指向的是哪个子类的实例,就能转换成哪个子类的引用。
强制转换前可做一个条件判断,如下:
if (c3 instanceof Cat){
Cat c4 =(Cat)c3; //这里报错,说c3 is Null,奇怪
c4.eat();
c4.play();
}else {
System.out.println("c3不是Cat类的实例,所以不能强制转换");
}
后面还会进一步探讨强制转换的问题~大家也可以在评论区留下你的看法,一起进步!