JavaSE---01类与对象
JavaSE---01类与对象
1 POP与OOP
POP:面向过程
OOP:面向对象
POP与OOP都是一种思想,面向对象是相对于面向过程而言的。面向过程强调的是功能行为、以函数为最小单位,考虑怎么做
。面向对象将功能封装进对象,强调具备了功能的对象,以类/对象为最小单位,考虑谁来做
2 面向对象特性
- 封装
把客观事物封装成抽象的类,并且类可以把自己的数据和方法只让可信的类或者对象操作,对不可信的进行信息隐藏。 - 继承
继承是一个对象获得另一个对象的属性的过程。就像是我们现实生活中的父子关系,儿子可以遗传父亲的一些特性,在面向对象语言中,就是一个类可以继承另一个类的一些特性,从而可以代码重用,其实继承体现的是is-a关系,父类和子类在本质上还是一类实体。
继承的特征:
1、可传递可扩展,若类C继承类B,类B继承类A(多继承)则类C既有从类B那里继承下来的属性与方法,也有从类A那里继承下来的属性与方法,还可以有自己新定义的属性和方法
2、可复用,若类B继承类A,那么建立类B时只需要再描述与基类(类A)不同的少量特征(数据成员和成员方法)即可。这种做法能减小代码和数据的冗余度,大大增加程序的重用性。
3、可维护性。继承通过增强一致性来减少模块间的接口和界面,大大增加了程序的易维护性。
科普:IS-A、IS-LIKE-A、HAS-A和USE-A都是用来便是类与类之间的关系
简单点就是:
- 如果继承过程中,仅仅是覆盖了父类中的方法,那就是IS-A关系;如果有新增的方法,则为IS-LIKE-A关系。
- 类B中的属性有类A,那就是HAS-A关系
- 类B中有关方法使用类A做为形参,这就是USA-A关系:例如 public void test(A a)
- 多态
多态就是同一个接口,使用不同的实例而执行不同操作
如果类A与类B是IS-A关系,那么就是 B is-a A ,A继承B,可以写成 A a = new B()
3 类与对象
- 类:是一个模板,它描述一类对象的行为和状态
- 对象[实例]:是类的一个实例(对象不是找个女朋友),有状态和行为。例如,一条狗是一个对象,它的状态有:颜色、名字、品种;行为有:摇尾巴、叫、吃等。
3.1 类与对象的创建
public class Dog{//模板,所有狗的共性
//属性
String breed;
int age;
String color;
//方法
void barking(){
}
void hungry(){
}
void sleeping(){
}
}
public static void main(String[] args){
//创建一个狗的实例(对象)
Dog dog = new Dog();
}
3.2 对象的创建分析
这里涉及了一点String常量池跟JVM知识点。不过只要你创建对象时使用关键字new那么这个对象是在堆里面生成的,变量引用堆中的地址
4 访问修饰符
成员变量有四种修饰符
- private 私有的
- default 默认不写
- protected 受保护的
- public 公共的
修饰符 | 当前类 | 同一包内 | 子孙类(同一包) | 子孙类(不同包) | 其他包 |
---|---|---|---|---|---|
public | Y | Y | Y | Y | Y |
protected | Y | Y | Y | Y/N |
Y |
default | Y | Y | Y | N | N |
private | Y | N | N | N | N |
对于除protected的其他访问权限可以很好理解:
1. public:在所有包中所有类中都可见
2. default :只能在同一个包下的类里面可见
3. private :只能在当前类中可见,不能修饰外部类
4.1 protected修饰符
对于protected修饰符要从两个方面分析:
1.
子类与基类在同一包中
:被声明为 protected 的变量、方法和构造器能被同一个包中的任何其他类访问;
2.子类与基类不在同一包中
:那么在子类中,子类实例可以访问其从基类继承而来的 protected 方法,而基类实例不能访问protected方法。
第2句的理解为下面的代码:
package p1;
public class Father1 {
protected void f() {} // 父类Father1中的protected方法
}
package p11;
import p1.Father1;
public class Son11 extends Father1 {
public static void main(String[] args) {
new Son11().f();
//new Father1().f();不能访问
}
}
4.2 protected修饰判断可见的规则
1.看访问的protected修饰的在哪个包下,那么这个包下所有类都能访问。
2.如果不在一个包下,看这个类是不是protected所在类的子类,如果是那么在这个类里,这个类的实例可以访问protected方法,但是这个类的父类实例不能访问【看不懂就看上面的2子类与基类不在同一包中】,如果不是子类,那么访问不了
5 static关键字
5.1 静态属性
- 当一个属性被static修饰的时候就叫做类属性,又叫做静态属性
- 当一个属性被声明成类属性,那么所有的对象,都共享一个值
- 与对象属性对比:
- 不同对象的 对象属性 的值都可能不一样。比如同学A与同学B的身高不同。
- 但是所有对象的类属性的值,都是一样的。比如同学A跟同学B都要考试。
- 访问类属性有两种方式:
- 对象.类属性
- 类.类属性(推荐)
5.2 静态方法
- 当一个方法被static修饰的时候就叫做类方法 ,又叫做静态方法
- 对象方法: 又叫实例方法,非静态方法
- 与对象属性对比:
- 访问一个对象方法,必须建立在有一个对象的前提的基础上
- 访问类方法,不需要对象的存在,直接就访问
- 调用类方法
- 对象.类方法;
- 类.类方法(推荐)
6 属性的初始化
6.1 对象属性初始化
对象属性初始化有3种【三种都有按照1,2,3的顺序执行】
- 声明该属性的时候初始化
- 初始化块
- 构造方法中初始化
public String name = "some hero"; //声明该属性的时候初始化
protected float hp;
float maxHP;
{
maxHP = 200; //初始化块
}
public Hero(){
hp = 100; //构造方法中初始化
}
优先级:1>2>3
6.2 类属性初始化
类属性初始化有2种【两种都有按照1,2顺序执行】
- 声明该属性的时候初始化
- 静态初始化块
public String name;
protected float hp;
float maxHP;
//物品栏的容量
public static int itemCapacity=8; //声明的时候 初始化
static{
itemCapacity = 6;//静态初始化块 初始化
}
public Hero(){
}
public static void main(String[] args) {
System.out.println(Hero.itemCapacity);
}
优先级:1>2
7 分析类创建时的执行过程
父类:
public class Father {
public String name;
protected float hp;
float maxHP;
//物品栏的容量
public static int father=8; //声明的时候 初始化
static{
father = 6;//静态初始化块 初始化
System.out.println("父类的静态代码块");
}
{
name="父亲";
System.out.println("父类的构造代码块");
}
public Father(){
System.out.println("父类的构造方法");
}
}
子类:
public class Son extends Father {
public String name;
protected float hp;
float maxHP;
//物品栏的容量
public static int son=8; //声明的时候 初始化
static{
son = 6;//静态初始化块 初始化
System.out.println("子类的静态代码块");
}
{
name="儿子";
System.out.println("子类的构造代码块");
}
public Son(){
System.out.println("子类的构造方法");
}
public static void main(String[] args) {
Son son = new Son();
}
}
输出结果:
父类的静态代码块
子类的静态代码块
父类的构造代码块
父类的构造方法
子类的构造代码块
子类的构造方法
执行过程:
当在main方法里面执行new Son()时,先去创建父类的静态属性,创建完成后执行父类的静态代码块,然后去子类创建子类的静态属性,创建完成后执行子类的静态代码块;之后先创建子类的对象属性再去父类创建对象属性,创建完成后执行父类的构造代码块,再执行父类的构造方法;之后执行子类的构造代码块,再执行子类的构造方法
上一篇: 缓存中间件-redis的sort和limit的核心原理
下一篇: java图像识别