一、封装
1.1封装的概念
面向对象程序设计,由于我们是让对象之间相互作用,我们并不需要知道对象是怎样具体操作的,我们只需要知道他有哪些功能,所以我们就可以把对象的一些功能封装起来,简单来说就是套壳屏蔽细节,比如电脑中只有一些usb接口,键盘,鼠标等来控制电脑运行,但是电脑实际运行的是其中的cpu,显卡,所以电脑把这些功能封装起来,我们只需要知道它有这些操作就行了,这就是封装的特性。
封装:将数据和操作数据的方法进行有机结合,隐藏对象的属性和实现细节,仅对外公开接口来和对象进行 交互
1.2访问限定符
在java中主要用类和访问修饰限定符来进行封装,类可以将数据以及封装数据的方法结合在一起
,符合人类的认知,而访问修饰限定则决定类中变量以及方法能否直接被类外调用。
No | 范围 | private | default | protected | public |
1 | 同一包中的类 | yes | yes | yes | yes |
2 | 同一包中的不同类 | yes | yes | yes | |
3 | 不同包的子类 | yes | yes | ||
4 | 不同包中的非子类 | yes |
图中的yes表示可以访问,其余表示不可被访问
default表示什么都不写时的权限,可以在同一个包中被访问
访问修饰限定符还可以限制类的访问权限
二、封装扩展之包
2.1包的概念
包相当于文件夹,将一系列文件放在一个文件夹里面,而众多的类需要管理,就可以用到包,一些相似功能的类可放入同一个包中管理
不同的包中还可以存在相同名称的类
2.2导入包中的类
在java中已经提供了很多的类供我们使用,比如C语言可以使用#include<>来导入一些头文件,java将类封装在包中,我们使用时可以使用import语句将包中的类导入到工程中就可以直接调用这个类
导入util这个包中的Date类就可以创建Date对象
import java.util.Date;
public class Test {
public static void main(String[] args) {
Date date = new Date();
// 得到一个毫秒级别的时间戳
System.out.println(date.getTime());
}
}
2.2自定义包
可以自己创建一个包用来管理自己的类,通常在文件的最上方加一条package语句可指定当前类在哪个包中,如果没有package语句,会默认放入src这个包中,创建方式如下
三、static关键字
在同一个类实例化多个对象时,我们会发现这些对象有很多共同的地方,那么会浪费很多内存空间,所以java将这些对象的共同点抽取出来,所有对象共享这一份,可以达到节省空间。static表示静态的,可以达到这一作用。
3.1static修饰成员变量
static修饰成员变量表示该变量是属于类的,并不依赖于对象,当类被加载时,该变量就被加载了,并且该变量只会被创建一次,在实例化对象时,所有对象共享这一份变量。
static使用:一般使用类名来调用静态成员,因为它属于类,不依赖于对象,但也可以通过对象访问,但不推荐
3.2static修饰成员方法
被static修饰的成员方法称为静态成员方法,是类的方法,不是某个对象所特有的,静态成员一般时通过静态方法来访问的。
特性:
1.不属于某个对象,是类的方法
2.可以通过对象调用,也可以通过类名.静态方法名(...)方式调用,更推荐使用后者
3.不能在静态方法中访问任何非静态成员以及非静态方法
4.静态方法不能被重写
3.3static成员初始化
1.就地初始化
在创建变量时直接进行赋值初始化称为就地初始化。例如
public class Student{
private String name;
private String gender;
private int age;
private double score;
private static String classRoom="301";
// ...
}
2.静态代码块初始化
文章后续部分介绍...
四、代码块
4.1代码块的概念
使用{}定义的一块代码称为代码块,代码块分为这四类
- 普通代码块
- 构造代码块
- 静态代码块
4.2普通代码块
定义在方法中,作用域为{}之间
4.3构造代码块
也叫做实例代码块,定义在类中的代码块,没有修饰限定符,用于初始化非静态成员变量,优先于构造方法调用
public class Dog {//类名
public String name;
public int age;
public String color;
{
this.name="小红";
this.age=2;
}
public void bark(){
System.out.println("汪汪汪");
}
//成员方法
}
4.4静态代码块
定义在类当中,使用static修饰,用于初始化静态成员变量,在加载类时优先实例代码块调用。
static {
classRoom = "306";
System.out.println("I am static init()!");
}
只会执行一次,在jvm加载类时直接调用,且只会执行一次。
五、继承
5.1继承的概念
继承就是将多个类的相同点抽取出来,将共性合并在一个类中,让这些类继承这个类,达到了代码复用性。比如猫和狗,它们都是动物,继承类似于“is a”的关系。
5.2继承的语法
继承需要使用关键字extends,语法格式如下,被继承的叫父类/基类/超类,继承的叫子类/派生类。
public class 子类 extends 父类{
...
}
继承过后,如果在子类中出现与父类同名的成员变量,优先使用子类自有的,如果子类没有,则再去父类中找,如果非要使用父类中同名的变量,可以使用super关键字,super.变量,来使用父类的成员。
5.3子父类初始化
必须优先初始化父类的成员变量,如果父类提供了有参构造方法,则在子类构造方法第一行提供一个super(参数列表...)语句,用来访问父类的构造方法。
例如,在Dog子类构造方法中,第一行必须优先初始化父类的成员,使用super()语句。
public class Animal {
public String name;
public int age;
public String color;
public Animal(String name, int age, String color) {
this.name = name;
this.age = age;
this.color = color;
}
}
public class Dog extends Animal{//类名
public String name;
public int age;
public String color;
public Dog(String name, int age, String color) {
super(name,age,color);
}
public void bark(){
System.out.println("汪汪汪");
}
//成员方法
}
5.4super和this
相同点:
- 都是关键字
- 只能在非静态方法中使用,用来访问非静态成员方法和变量
- 在构造方法中调用时,只能在第一行,并且两者不能同时存在
不同点:
- this是当前对象的引用,super是用来访问父类的字段和方法
- 在非静态成员方法中,this用来访问本类的方法和属性,super用来访问父类继承下来的方法和属性
- 在构造方法中:this(...)用于调用本类构造方法,super(...)用于调用父类构造方法,两种调用不能同时在构造 方法中出现
- 构造方法中一定会存在super(...)的调用,用户没有写编译器也会增加,但是this(...)用户不写则没有
六、final关键字
当一个变量想变成常量时,可以用final修饰,当一个方法不想被重写时,也可以用final修饰,当一个类不想再被继承时,可以用final修饰,表示该类不可被继承。
final public class Dog{
...
}
Dog类不再能被继承
七、多态
多态字面意思是一件事情,不同的人做有不同的状态,比如吃饭,猫吃猫粮,狗吃狗粮。
7.1多态的概念
对于不同的对象,在实现父类的同一个方法时,会呈现出不同的效果,称为多态。
7.2多态实现条件
多态在java中实现需要三个条件
- 在继承体系下
- 子类必须对父类中方法进行重写
- 通过父类的引用调用重写的方法
在代码运行时,会执行子类中自己重写的方法。
public class Animal {
public String name;
public int age;
public String color;
public Animal(String name, int age, String color) {
this.name = name;
this.age = age;
this.color = color;
}
public void eat(){
System.out.println(name+" 吃饭");
}
}
public class Cat extends Animal{
public Cat(String name,int age,String color){
super(name,age,color);
}
@Override
public void eat() {
System.out.println(name+" 吃猫粮");
}
}
public class Dog extends Animal{//类名
public Dog(String name, int age, String color) {
super(name,age,color);
}
@Override
public void eat() {
System.out.println(this.name+" 吃狗粮");
}
public void bark(){
System.out.println("汪汪汪");
}
//成员方法
}
public static void main(String[] args) {
Animal dog=new Dog("小黑",2,"黑色");
Animal cat=new Cat("小白",1,"白色");
dog.eat();
cat.eat();
}
在两个子类中重写了方法后,通过父类的引用引用了对应子类的对象,调用父类中被重写的方法后,运行时会调用子类中重写后的方法,因此不同对象实现同一方法呈现不同的状态。
7.3重写的规则
- 方法名,参数列表必须相同,返回值类型可以不同,但是得同样具体父子类关系
- 访问修饰限定符不能比父类还低,必须大于等于父类
- 不能重写父类final,static修饰的方法