面向对象编程(中级)

---学习笔记(阿B韩顺平老师)

基本语法

package com.pak1;

1. package  关键字,表示打包

2. com.pak1 表示包名

包的导入:

1. import java.util.Scanner; //表示只会引入java.util 包下的Scanner

2. import java.util.*; //表示会引入java.util 包下的所有类

包的命名规则:与变量命名规则一样

包的命名规范:

com.公司名.项目名.业务模块名

举例:

1. com.sina.crm.user //用户模块

2. com.sina.crm.order //订单模块 

访问修饰符

Java访问修饰符:

1. 公开级别: public ,对外公开

2. 受保护级别: protected ,对子类和同一个包中的类公开

3. 默认级别: 空,  向同一个包的类公开

4. 私有级别: private ,不对外公开,只有类本身可以访问

注意:

1. 成员方法和属性一样,如上表所示,四个修饰符都可以修饰

 2. 类只有public 和 默认 能修饰

封装

介绍:封装(encapsulation)就是把抽象出的数据[属性]和对数据的操作[方法]封装在一起,数据被保护在内部,程序的其他部分只有通过被授权的操作[方法],才能对数据进行操作。

封装的实现方法:

1. 将数据[属性]私有化(private),不能直接修改或访问属性

2. 提供一个公共的set方法,用于对属性判断并赋值:

                public void setXxx(类型  参数名){

                        属性 = 参数名;

                }

3. 提供一个公共的get方法,用于获取属性的值

                public 类型 getXxx(){

                        return xxx

                }

提示:上面步骤2、3可用快捷键 Alt + Insert 实现

封装与构造器

封装可以和构造器配合使用,具体操作就是在构造函数中去调用setXxx or getXxx

继承

前言:

继承可以解决代码复用,当多个类存在相同的属性和方法时,可以从这些类中抽象出父类,在父类中定义这些相同的属性和方法,所有的子类不需要重新定义这些属性和方法,只需通过extends来声明继承即可。

基本语法

class 子类类名 extends 父类类名{

        //子类会自动拥有父类定义的属性和方法
}

细节:

1. 子类继承了父类的属性和方法,但是父类中的私有属性和私有方法还是不能直接使用,而要通过公共的方法去访问。

2. 子类必须调用父类的构造器来完成父类的初始化

3. 当创建子类对象时,不管子类使用了哪种构造器,都会默认去调用父类的无参构造器,如果父类没有提供无参构造器,那么必须在子类的构造器中用super()来指定父类用哪个构造器来完成父类的初始化。

4. 如果希望指定去调用父类的某个构造器,则需要显式的调用一下。  super()

5. super() 和this() 都只能放在构造器的第一行,也就意味着,它们不能同时出现在一个构造器中。

6. Java中所有类都是Object类的子类。

7. 父类构造器的调用不限于直接父类,将一直往上追溯到Object类(“神父”,顶级父类)

8. Java中是单继承机制,也就是一个子类只能继承一个父类。但是父类也能继承属于它的父类,(谁没有个父呢)

细细节:

从父类、爷类、姥爷类等等寻找数据返回信息需遵守以下规则:

1.首先看子类是否有该属性,若有,并且可以访问,则返回信息

2. 若子类没有该属性,就看父类有无该信息,若有,并且可以访问,就返回信息

3. 若父类没有,就看爷类,看佬爷类,看佬佬爷类,指导Object类...

请注意:不管在哪”一辈“的类中查找到该属性,就算它不能直接访问(被私有化),也不会再往上查找了。

找方法和找属性规则一样。

super

首先注意区分super()、this()和super.xx 、 this.xx 的区别:

前者是调用父类和本类的构造器,并且只能出现在某个构造器的第一行。

后者是调用父类或本类的属性或方法。

当然,super.xx 和this.xx 调用方法规则与上面的细细节一样,只不过,super是从父类开始的。

另外,this.xx 等同与直接调用 xx  ,(this并不局限于本类,若本类找不到,也是会向上查找的,与直接调用一个效果)

另另外,super.xx也不局限于父类,父类找不到的话,也会去爷类等去寻找。

方法重写

方法重写(覆盖)是子类有个方法,和父类的某个方法名称、参数、返回类型都一样,就是方法重写。(跟重载有些类似,不过是子类与父类之间的重名问题)

使用细节:

1. 子类的名称、参数要和父类的方法名称、参数完全相同。

2. 子类的返回类型也要和父类的相同,或者是父类返回类型的子类。比如:父类的返回类型是Object,子类的返回类型是String。(注意,Object类是一切类的基类)

3. 子类方法不能缩小父类方法的访问权限(访问权限:public > protected > 默认 > private)

多态

多态有方法多态和对象多态。方法多态从方法重载和重写就得以体现,下面主要说对象多态。

对象的多态

Animals animal = new Dog(); // 编译类型Animals  运行类型Dog,(Dog 是 Animals 的子类)

定义对象时,=(等号)左边时编译类型,=右边是运行类型。(javac-编译,java-运行)

1. 一个对象的编译类型和运行类型可以不一致。

2. 编译类型在定义对象时就确定了,不能改变。

3. 运行类型可以变化的。(向上转型)

 向上转型

多态的前提:两个对象(类)存在继承关系。

本质: 父类的引用指向了子类的对象

语法: 父类类型  引用名  =  new  子类类型();  // 就比如上面的 Animals animal = new Dog();

特点:     1. 左边编译类型,右边运行类型。 

                2. 可以调用父类的所有的所有成员(需遵守访问权限),

                3. 不能调用子类的特有成员。(需要向下转型才可以)

                对于2 和3 原因是因为在编译阶段,能调用哪些成员,是由编译类型决定的

                4. 最终运行效果子类的具体实现,即调用方法时,按照从子类开始查找,然后调用的规则,就是前面所说的细细节规则。

向下转型

1. 语法:  子类类型  引用名  =  (子类类型)父类引用;

2. 只能强转父类的引用,不能强转父类的对象;

3. 要求父类的引用必须指向的是当前目标类型的对象。

4. 可以调用子类类型中所有成员。

向下转型是为了调用那些子类中的特有成员。

“重写问题”

补充:关键字 a instanceof b,  a是b的子类就返回true,否则返回false。

属性没有重写之说。 属性的值看编译类型,方法看运行类型。

看下面例题。

public class PolyExercise {
    public static void main(String[] args) {
        Sub s = new Sub(); //创建一个Sub对象s. s的编译类型Sub, 运行类型Sub
        System.out.println(s.num); //200 输出s的属性num
        s.display(); //200 调用方法

        Base b = s; // b 的编译类型是Base 运行了类型是Sub
        System.out.println(b == s); // true 因为b 和 s 指向的是同一个对象
        System.out.println(b.num); // 100, 属性看编译,编译类型是Base,所以是Base类里面的num 100
        b.display(); // 200 方法看运行,运行类型是Sub,从Sub类开始查找display方法

    }
}

class Base{
    int num = 100;
    public void display(){
        System.out.println(this.num);
    }
}

class Sub extends Base{
    int num = 200;
    public void display(){
        System.out.println(this.num);
    }
}

动态绑定机制

1. 当调用对象方法的时候,该方法会和该对象的运行类型(内存地址)绑定。

2. 当调用对象属性时,没有动态绑定机制,哪里声明,使用哪里的属性。

看以下例题。当注释掉B类中的sum()方法和sum1()方法,结果又当如何。(30,20)

多态数组 

数组的定义类型是父类类型,里面保存的元素可以是父类类型,也可以是各个子类类型。

其中Student和Teacher都是Person的子类

多态参数 

方法定义的形参类型为父类类型,实参类型允许为子类类型。

Object类中的一些方法

equals 与 ==

== 可以判断基本类型和引用类型,判断基本类型时,判断是否相等;判断引用类型时,判断地址是否相等,即判断是否为同一个对象。

而equals只能判断引用类型(equals是Object类中的方法),默认判断的是地址是否相等,但是子类经常会重写该方法(例如 String 类、Integer 类)

JDK查看源码

光标放上去,按快捷点ctrl + B

hashCode

xx.hashCode();

特点:

1. 提高具有哈希结构的容器的效率!

2. 两个引用,若指向的是同一个对象,则哈希值一定相同!

3. 两个引用,若指向的是不同对象,则哈希值是不一样的(也不绝对,但概率极低)。

4. 哈希主要是根据地址号得来的,但不能完全将哈希值等价于地址

toString

基本介绍:默认会返回: 全类名+@+哈希值的十六进制

       子类往往会重写该方法 ;                全类名就是包名+类名。 

快捷键 Alt + Insert 重写该方法,一般会输出该对象的属性值

直接输出对象时,toString 方法会默认被调用。

Dog dog = new Dog();

System.out.println(dog); //直接输出对象。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值