5.包,面对对象的三要素

1.命名规则

只能包含数字、字母、下划线、小圆点、但是不能用数字开头,不能是关键字和保留字

2.命名规范

一般是小写字母+小圆点
一般是 com.公司名.项目名.业务模块名
比如:
com.sina.crm.user//用户模块
com.sima.crm.order//订单模块
com.sina.crm.utils//工具类

3.常用的包

1.java.lang.* //lang包是基础包,默认引入,不需要在引入
2.java.util.* //util包,系统提供的工具包,工具类,使用Scanner
3.java.net.* //net包,网络包,网络开发
4.java.awt.* //是做java的界面开发,GUI
例:用Arrays给数组排序

1
2
3
4
5
6
7
8
9
10
import java.util.Arrays;
public class Import01{
public static void main(String[]args){
int [] arr = {-1,20,2,13,3};
Arrays.sort(arr);
for(int i = 0;i<arr.length;i++){
System.out.print(arr[i]+"\t")
}
}
}

4.访问修饰符

用来控制方法和属性(成员变量)的访问权限(范围)
1.公开级别:用public修饰,对外公开
2.受保护级别:用protected修饰,对子类和同一个包中的类公开
3.默认级别:没有修饰符号,向同一个包的类公开
4.私有级别:用private修饰,只有类本身可以访问,不对外公开

访问级别 访问控制 本类 同包 子类(继承) 不同包
公开 public
受保护 protected ×
默认 没有修饰符 × ×
私有 private × × ×
注意事项:
1.修饰符可以用来修饰类中的属性,成员方法以及类
2.只有默认的和public才能修饰类!
3.成员方法的访问规则和属性完全一样。

5.面向对象编程三大特征-封装

  1. 定义:把抽象出来的数据(属性)和对数据的操作(方法)封装在一起,数据被保护在内部,程序的其他部分只有同伙被授权的操作(方法),才能对数据进行操作。
    封装的好处:隐藏实现细节
  2. 封装的实现步骤:
    1.将属性进行私有化private[不能直接修改属性]
    2.提供一个公共的set方法,用于对属性判断并赋值
    1
    2
    3
    public void Set Xxx(类型 参数名){
    属性=参数名;
    }
    3.提供一个公共的get方法,用于获取属性的值
    1
    2
    3
    public 数据类型 get Xxx(){
    return xx;
    }
    简而言之:封装就是利用get和set方法对传入的值可以加以判断,如果自己写了构造方法,则会绕过get和set方法,不能判断,所以可以这样写构造方法.
    1
    2
    3
    4
    public Person(String name,int age){
    setName(name);
    SetAge(age);
    }

    5.面向对象编程三大特征-继承

    主要解决了两个类中的方法有很多是相同的。
    关键字:extends
    语法:class 子类 extends 父类。
    继承的细节:
  3. 子类继承了所有父类的属性和方法,但是私有属性和方法不能在子类直接访问,要通过公共的方法区访问。
  4. 当创建子类的对象时,不管使用子类的哪个构造器,默认情况下总会调用父类的无参构造器,如果父类没有提供无参构造器,则必须在子类的构造器中用super去指定使用父类的哪个构造器完成对父类的初始化工作,否则编译错误。
  5. 如果希望指定去调用父类的某个构造器,则显式的调用一下:super(参数列表)。
  6. super()和this()都只能在构造器第一行,因此这两个方法不能共存在一个构造器。

    super关键字

  7. 定义:super代表父类的引用,用于访问父类的属性、方法、构造器
  8. 当子类中有和父类中的成员(属性和方法),重名时,必须通过super+方法名。如果没有重名,则可以用this+方法名和super+方法名或直接访问是一个效果。注意:super可以跳过本类直接去找父类,如果本类有和父类一样的方法,则执行父类的方法。总而言之:子类和父类有一样的方法则系统会优先使用子类的,this和直接访问方式,如果使用了super+方法名则去访问父类的方法。

    6.方法重写

    名称 发生范围 方法名 形参列表 返回类型 修饰符
    重载 本类 必须一样 类型,个数或者顺序至少有一个不同 无要求 无要求
    重写 父子类 必须一样 相同 子类重写的方法返回的类型和父类返回的类型一致,或是其子类 子类方法不能缩小父类方法的使用范围

    7.面向对象编程三大特征-多态

    多态=多种状态
    方法的多态:重写和重载就能体现多态
    JAVA中的多态主要表现为方法的多态,主要是方法重载和方法重写的表现.
    方法重载实现的是静态多态性,又称编译多态,在编译阶段确定调用哪个重载方法
    方法重写实现的是动态的多态性,又称运行多态,在运行阶段确定调用哪个重载的方法
    JAVA中方法的重载包括成员方法和构造方法的重载
    对象的多态:
  9. 一个对电工的编译类型和运行类型可以不一致
  10. 编译类型在定义对象时,就确定了,不能改变
  11. 运行类型是可以变化的
  12. 编译类型看定义时 = 号的左边,运行类型看 = 号的右边
    例:
    Animal animal = new Dog();
    //animal编译类型是Animal,运行类型Dog;
    animal = new Cat();
    //animal的运行类型编程了cat,但编译类型还是Animal;

    向上转型:

    多态的前提是:两个对象(类)存在继承关系
    多态的向上转型
  13. 本质:父类的引用指向了子类的对象
  14. 语法:父类类型 引用名 = new 子类类型();
  15. 特点1:编译类型看左边,运行类型看右边
  16. 特点2:可以调用父类中的所有成员(遵守访问权限)
  17. 特点3:不能调用子类中的特有成员,最终运行效果看子类的具体实现。
    例:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    class Animal{
    String name = "动物";
    int age = 10;
    public void sleep(){
    System.out.println("睡");
    }
    public void run(){
    System.out.println("跑");
    }
    public void eat(){
    System.out.println("吃");
    }
    public void show(){
    System.out.println("hello,你好");
    }
    }
    class cat extends Animal{
    public void eat(){
    System.out.println("猫吃鱼");
    }
    public void catchMouse(){
    System.out.println("猫抓老鼠");
    }
    }
    public class test{
    public static void main(String[] args){
    Animal animal = new cat();//向上转型。
    animal.xxx;//可以调用父类的所有方法(遵守访问权限),不能调用cat的catchMouse方法。
    //不能调用子类的特有成员.(向下转型可以解决)
    //因为在编译阶段,能调用哪些成员,是由编译类型决定的。
    animal.eat();//输出猫吃鱼
    //因为运行时,执行到该行时,animal运行类时cat,所以eat就是cat的eat
    animal.run();//输出跑
    }
    }

    向下转型:

  18. 语法:子类类型 引用名 = (子类类型) 父类引用;
  19. 只能强转父类的引用,不能强转父类的对象
  20. 要求父类的引用必须指向的是当前目标类型的对象
  21. 当向下转型后可以调用子类类型中所有的成员
    例:
    1
    2
    3
    4
    //上例中的animal.catchMouse调用报错,可以用向下转型。
    //语法:子类类型 引用名 = (子类类型) 父类引用;
    Cat cat = (Cat) animal;//编译类型是cat,运行类型是cat。
    cat.catchMouse();//即可调用。
    小细节:
  22. 属性没有重写之说!属性的值看编译类型。
  23. instanceOf比较操作符,用于判断对象的运行类型是否为XX类型或XX类型的子类型。
    例子:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    class Base{
    int count = 10;
    public void display(){
    System.out.println(this.count);
    }
    }
    class Sub extends Base{
    int count = 20;
    public void display(){
    System.out.println(this.count);
    }
    }
    public class Test{
    public static void main(String[]args){
    Sub s = new Sub();//注意运行类型和编译类型,运行类型为Sub,编译类型为 Sub.
    System.out.println(s.count);
    s.display();
    Base b = s;
    System.out.println(b==s);
    System.out.println(b.count);
    b.display(); //注意运行类型和编译类型,运行类型为Sub,编译类型为 Base.
    }
    }
    /*输出结果为:
    20
    20
    True
    10
    20
    */

    8.JAVA动态绑定机制

  24. 当调用对象方法的时候,该方法会和该对象的内存地址/运行类型绑定
  25. 当调用对象属性时,没有动态绑定机制,哪里声明,哪里使用
    例:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    class A{
    public int i = 10;
    public int sum(){
    return geti()+10;
    }
    public int sum1(){
    return i+10;
    }
    public int geti(){
    return i;
    }
    }
    class B extends A{
    public int i = 20;
    public int sum(){
    return i + 20;
    }
    public int geti(){
    return i;
    }
    public int sum1(){
    return i+10;
    }
    }
    public static void main(String[]args){
    A a = new B();
    //编译看左边,运行看右边
    //a的编译类型A 运行类型B
    //即调用的方法先看运行类型中有没有
    System.out.println(a.sum()); //40
    System.out.println(a.sum1()); //30
    //如果把子类的sum方法注释,注意geti获得的值(调用的是子类的geti),此例中获得的是子类的geti的值,所以父类的sum方法为20+10=30。
    /*
    如果把B类的sum1方法注释,则执行父类的sum1方法,此时i的值为父类i的值,因为属性没有动态绑定机制。
    */
    }

    9.多态数组

    定义:数组的定义类型为父类型,里面保存的实际元素类型为子类类型。
    例:现有一个继承结构如下,要求创建一个Person对象、2个Student对象和2个Teacher对象,统一放在数组中,并调用每个对象say方法。
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    public class Person{
    private String name;
    private int age;
    public Person(String name,int age){
    this.name=name;
    this.age=age;
    }
    public void setName(String name){
    this.name=name;
    }
    public String getName(){
    return name;
    }
    public void setAge(int age){
    this.age=age;
    }
    public int getAge(){
    return age;
    }
    public String say(){
    return name + "\t" + age;
    }
    }
    public class Student extends Person{
    private double score;
    public Student(String name,int age,double score){
    super(name,age);
    this.score = score;
    }
    public void setScore(double score){
    this.score = score;
    }
    public String getScore(){
    return score;
    }
    //重写父类的say方法
    public String say(){
    return super.say()+ "score="+score;
    }
    }
    public class Teacher extends Person{
    private double salary;
    public Teacher(String name,int age,double salary){
    super(name,age);
    this.salary=salary;
    }
    public void setSalary(double salary){
    this.salary=salary;
    }
    public double getSalary(){
    return salary;
    }
    }
    //重写父类的say方法
    public String say(){
    return super.say() + "salary" + salary;
    }
    //主方法
    public static void main(String [] args){
    Person[] persons = new Person[5];
    persons[0] = new Person("jack",20);
    persons[1] = new Student("jack",20,100);
    persons[2] = new Student("jack",20,30);
    persons[3] = new Teacher("haozi",30,20000);
    persons[3] = new Teacher("haozi",30,40000);
    for(int i = 0;i<persons.length;i++){
    //person[i]的编译类型是Person,运行类型是Perosn、Student、Teacher。
    System.out.println(persons[i].say());//动态绑定
    }
    }
    //升级:如果Teacher和Student类中都有一个自己的方法,则可以用向下转型。
    /*
    if(persons[i] instanceof Student){
    Student student = (Student)person[i]//向下转型
    student.study();
    //一条语句执行:((Student)persons[i]).study;
    }else if(persons[i] instanceof Teacher){
    ......
    }
    */
    扩展:==和equals的对比
  26. ==:既可以判断基本类型,又可以判断引用类型
  27. ==:如果判断及基本类型,判断的是值是否相等
  28. ==:如果判断引用类型,判断的是地址是否相等,即判定是不是同一个对象
    equals方法(只能判断引用类型)
  29. 默认判断的是地址是否相等,子类中往往重写该方法,用来判断内容是否相等,比如Integer,String

hashCode方法(后面会具体讲)

  1. 提高具有哈希结构的容器效率
  2. 两个引用,如果指向的是同一个对象,则哈希值肯定是一样的,否则哈希值是不一样的
  3. 哈希值主要是根据地址号来的,不能完全将哈希值等价于地址
    toString方法:返回该对象的字符串表示
  4. 默认返回:全类名+@+哈希值的十六进制
  5. 重写toString方法,打印对象或拼接对象时,都会调用该对象的toString形式
  6. 直接输出一个对象时,toString方法会被默认调用

Finalize方法

  1. 当对象被回收时,系统会自动调用该对象的finalize方法。子类可以重写该方法,释放资源
  2. 垃圾回收机制的调用,是由系统来决定,也可以通过System.gc()主动触发垃圾回收机制

5.包,面对对象的三要素
http://example.com/2022/09/29/java/5.包/
作者
haozi0o0
发布于
2022年9月29日
许可协议