欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 新闻 > 资讯 > 6-2.Java 面向对象 - 中级(包、访问修饰符、封装、继承、super、方法重写、多态、动态绑定机制、面向对象相关方法)

6-2.Java 面向对象 - 中级(包、访问修饰符、封装、继承、super、方法重写、多态、动态绑定机制、面向对象相关方法)

2024/11/8 4:45:18 来源:https://blog.csdn.net/weixin_52173250/article/details/143604751  浏览:    关键词:6-2.Java 面向对象 - 中级(包、访问修饰符、封装、继承、super、方法重写、多态、动态绑定机制、面向对象相关方法)

一、包

1、基本介绍
  • 包的本质就是创建不同的文件夹来保存类文件
  1. 定义包
package 【包名】;
  1. 引入包
import 【包名】;
2、包的作用
  1. 区分相同名字的类

  2. 可以很好的管理类

  3. 控制访问权限

3、包的命名
(1)基本介绍
  • 命名规则:只能包含数字、字母、下划线、小圆点,不能用数字开头,不能是关键字或保留字

  • 命名规范:一般是小写字母 + 小圆点

(2)演示
  1. 公司开发
com.【公司名】.【项目名】.【业务模块名】;
  1. 团队开发
team.【团队名】.【项目名】.【业务模块名】;
4、常用包
说明
java.lang.*基本包,默认引用
java.util.*系统提供的工具包,有大量工具类
java.net.*网络包
java.awt.*GUI
5、注意事项
  1. package:作用是声明当前类所在包,需要放在最上方,一个类中最多只有一条 package 语句

  2. import:需要放置在 package语句下方


二、访问修饰符

1、基本介绍
  1. 公开级别:public,对外公开

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

  3. 默认级别:无修饰符,向同一个包的类公开

  4. 私有级别:private,只有类本身可以访问

访问级别访问修饰符同类同包不同类(不含子类)同包子类不同包不同类(不含子类)不同包子类
公开public
受保护protected-√(注意)
默认无修饰符--
私有private----
2、注意事项
  1. 访问修饰符可以用来修饰类中的属性,成员方法

  2. 只有 public 和无修饰符才能修饰类

3、演示
  1. 同类
package com.my.modifier;public class A {public int n1 = 100;protected  int n2 = 200;int n3 = 300;private int n4 = 400;public void m() {System.out.println(n1);System.out.println(n2);System.out.println(n3);System.out.println(n4);}
}
  1. 同包不同类(不含子类)
package com.my.modifier;public class B {public void m() {A a = new A();System.out.println(a.n1);System.out.println(a.n2);System.out.println(a.n3);
//        System.out.println(a.n4); // 'n4' has private access in 'com.my.modifier.A'}
}
  1. 不同包不同类
package com.my.modifier.test;import com.my.modifier.A;public class C {public void m() {A a = new A();System.out.println(a.n1);
//        System.out.println(a.n2); // 'n2' has protected access in 'com.my.modifier.A'
//        System.out.println(a.n3); // 'n3' is not public in 'com.my.modifier.A'. Cannot be accessed from outside package
//        System.out.println(a.n4); // 'n4' has private access in 'com.my.modifier.A'}
}
  1. 同包子类
package com.my.modifier;public class Ac1 extends A {public void m() {System.out.println(n1);System.out.println(n2);System.out.println(n3);
//        System.out.println(n4); // 'n4' has private access in 'com.my.modifier.A'}
}
  1. 不同包子类
package com.my.modifier.test;import com.my.modifier.A;public class Ac2 extends A {public void m() {System.out.println(n1);System.out.println(n2);
//        System.out.println(a.n3); // 'n3' is not public in 'com.my.modifier.A'. Cannot be accessed from outside package
//        System.out.println(a.n4); // 'n4' has private access in 'com.my.modifier.A'}
}

三、封装

1、基本介绍
  • 把数据和对数据的操作进行封装,数据被保护在内部,只有通过被授权的操作才能对数据进行操作
2、封装的好处
  1. 隐藏实现细节

  2. 对数据进行验证,保证安全合理

3、封装的实现步骤
  1. 将属性私有化

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

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

4、具体实现
  • Person.java
package com.my.intermediate;public class Person {private String name;private int age;public Person(String name, int age) {this.name = name;this.age = age;}// 获取 name 的 get 方法public String getName() {return name;}// 设置 name 的 set 方法public void setName(String name) {this.name = name;}// 获取 age 的 get 方法public int getAge() {return age;}// 设置 age 的 set 方法public void setAge(int age) {this.age = age;}
}

四、继承

1、基本介绍
  • 当多个类存在相同的属性和方法时,可以从中抽取出父类,在父类中定义相同的属性和方法,子类则只需继承父类
class 子类 extends 父类 {}
  1. 父类又名超类,基类

  2. 子类又名派生类,子类会拥有父类定义的属性和方法

2、注意事项
  1. 子类继承了父类所有的属性和方法,但是子类不能直接访问父类的私有属性,需要通过公共的方法

  2. 子类创建对象时会调用父类的无参构造器,完成父类初始化

  3. 子类创建对象时,如果父类没有提供无参构造器,则必须在子类的构造器中使用 super 指定使用父类的某个构造器完成父类初始化

  4. 显式调用父类的构造器

super(【参数列表】);
  1. super 需要放置在构造器的第一行

  2. super 和 this都只能放在构造器第一行,二者不能共存

  3. Java 中的所有类都是 Object 的子类

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

  5. 子类最多只能继承一个父类

3、具体实现
  • ExtendsTest.java
package com.my.intermediate;public class ExtendsTest {public static void main(String[] args) {Student student = new Student("小明", 12);Teacher teacher = new Teacher("张老师", 30);student.say();teacher.say();}
}// 父类
class People {private String name;private int age;public People(String name, int age) {this.name = name;this.age = age;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}
}// 子类
class Student extends People {public Student(String name, int age) {super(name, age);}public void say() {System.out.println("我是学生" + getName());}
}// 子类
class Teacher extends People {public Teacher(String name, int age) {super(name, age);}public void say() {System.out.println("我是老师" + getName());}
}

五、super

1、基本介绍
  • super 代表父类的引用,用于访问父类的属性,方法,构造器
  1. 访问父类属性,但不能访问父类的私有属性
super.【属性名】;
  1. 访问父类方法,但不能访问父类的私有方法
super.【方法名】;
  1. 访问父类构造器
super(【参数列表】);
2、super 的好处
  • 调用父类构造器,分工明确,父类属性由父类初始化,子类属性由子类初始化
3、注意事项
  1. 子类和父类中的成员(属性或方法)重名时,访问父类成员,必须使用 super,如果没有重名,使用 super 和 this 访问效果一致

  2. super 的访问不限于直接父类,如果多个基类中都有同名的成员,super 的访问遵循就近原则


六、方法重写

1、基本介绍
  • 方法重写就是子类有一个方法,和父类的某个方法的名称,返回类型,参数一致
2、注意事项
  1. 子类重写方法的形参列表,方法名称,要和父类方法的形参列表,方法名称一致

  2. 子类重写方法的返回类型和父类的返回类型一致,或者是父类返回类型的子类

  3. 子类重写方法不能缩小父类方法的访问权限

3、具体实现
  • OverwriteTest.java
package com.my.intermediate;public class OverwriteTest {public static void main(String[] args) {Dog dog = new Dog();dog.shout();}
}class Animal {// 父类的 shout 方法public void shout() {System.out.println("动物哇哇叫!!!");}
}class Dog extends Animal{// 进行方法重写,父类的 shout 方法@Overridepublic void shout() {System.out.println("小狗汪汪叫!!!");}
}

七、多态

1、基本介绍
  • 方法或对象具有多种形态,建立在封装和继承的基础之上
2、多态的具体体现
(1)方法的多态
  • 方法的重载和重写体现多态
(2)对象的多态
  1. 一个对象的编译类型和运行类型可以不一致
Animal animal = new Dog(); // 编译类型是 Animal,运行类型是 Dog
animal = new Cat(); // animal 的运行类型变为 Cat,编译类型仍是 Animal
  1. 对象的编译类型在定义对象时就确定了,不能改变

  2. 对象的运行类型是可以改变的

3、注意事项
  1. 多态的前提是两个对象(类)存在继承关系

  2. 属性没有重写

4、具体实现
  • PolyObjectTest.java
package com.my.intermediate;public class PolyObjectTest {public static void main(String[] args) {Person person1 = new Student();Person person2 = new Driver();person1.say();person2.say();}
}class Person {public void say() {System.out.println("自我介绍");}
}class Student extends Person {@Overridepublic void say() {System.out.println("我是学生");}
}class Driver extends Person {@Overridepublic void say() {System.out.println("我是司机");}
}
5、补充
(1)向上转型
  • 本质是父类的引用指向子类的对象
【父类类型】 【引用名】 = new 【子类类型】();
  • 可以调用父类的所有成员,但需遵守访问权限,不能调用子类的特有成员
(2)向下转型
【子类类型】 【引用名】 = (【子类类型】) 【父类引用】;
  1. 只能强转父类的引用,不能强转父类的对象

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

  3. 可以调用子类中的所有成员

(3)instanceOf 比较操作符
  • 判断对象的运行类型是否为某类型或某类型的子类型
6、多态的应用
(1)基本介绍
  1. 多态参数:方法定义的形参类型为父类类型,实参类型允许为子类型

  2. 多态数组

(2)具体实现
  • PolyObjectExercise.java
package com.my.intermediate;public class PolyObjectExercise {public static void main(String[] args) {Master master = new Master("杰克");Dog dog = new Dog("阿黄");Cat cat = new Cat("咪咪");Meat meat = new Meat("肉");Fish fish = new Fish("鱼");master.feed(dog, meat);master.feed(cat, fish);// 测试向上转型System.out.println("====================");Animal animal1 = new Dog("大黄");animal1.sleep(animal1);// 测试向下转型System.out.println("====================");Animal animal2 = new Cat("大橘");Cat myCat = (Cat) animal2;myCat.shout(myCat.getName());// 测试比较操作符System.out.println("====================");System.out.println(dog instanceof Dog);System.out.println(dog instanceof Animal);}
}class Master {private String name;public Master(String name) {this.name = name;}public String getName() {return name;}public void setName(String name) {this.name = name;}public void feed(Animal animal, Food food) {System.out.println("主人" + this.getName() + "给" + animal.getName() + "喂食" + food.getName());}
}class Animal {private String name;public Animal(String name) {this.name = name;}public String getName() {return name;}public void setName(String name) {this.name = name;}public void sleep(Animal animal) {System.out.println(animal.name + "在睡觉");}
}class Food {private String name;public Food(String name) {this.name = name;}public String getName() {return name;}public void setName(String name) {this.name = name;}
}class Dog extends Animal {public Dog(String name) {super(name);}
}class Cat extends Animal {public Cat(String name) {super(name);}public void shout(String name) {System.out.println(name + "喵喵叫");}
}class Meat extends Food {public Meat(String name) {super(name);}
}class Fish extends Food {public Fish(String name) {super(name);}
}
  • PolyArrTest.java
package com.my.intermediate;public class PolyArrTest {public static void main(String[] args) {Person[] persons = new Person[5];persons[0] = new Person("杰克", 20);persons[1] = new Teacher("张老师", 30, 3000);persons[2] = new Teacher("王老师", 40, 4000);persons[3] = new Student("小明", 12, 89);persons[4] = new Student("小李", 14, 78);// 遍历多态数组for (int i = 0; i < persons.length; i++) {if (persons[i] instanceof Student) {((Student) persons[i]).study();} else if (persons[i] instanceof Teacher) {((Teacher) persons[i]).teach();} else {System.out.println(persons[i].say());}}}
}class Person {private String name;private int age;public Person(String name, int age) {this.name = name;this.age = age;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}public String say() {return "name: " + name + ", age: " + age;}
}class Student extends Person {private double score;public Student(String name, int age, double score) {super(name, age);this.score = score;}public double getScore() {return score;}public void setScore(double score) {this.score = score;}@Overridepublic String say() {return super.say() + "  score:" + score;}// 特有方法public void study() {System.out.println(this.getName() + "在学习");}
}class Teacher extends Person {private double money;public Teacher(String name, int age, double money) {super(name, age);this.money = money;}public double getMoney() {return money;}public void setMoney(double money) {this.money = money;}@Overridepublic String say() {return super.say() + "  money" + money;}// 特有方法public void teach() {System.out.println(this.getName() + "在教学");}
}

八、动态绑定机制

1、基本介绍
  1. 当调用对象方法时,该方法会和该对象的内存地址 / 运行类型绑定

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

2、演示
  • DynamicBindingTest.java
package com.my.intermediate;public class DynamicBindingTest {public static void main(String[] args) {A a = new B();System.out.println(a.sum());System.out.println(a.newSum());}
}class A {int i = 10;public int sum() {return getI() + 10;}public int newSum() {return i + 10;}public int getI() {return i;}
}class B extends A {int i = 20;//    public int sum() {
//        return i + 20;
//    }public int newSum() {return i + 10;}public int getI() {return i;}
}
  • 输出结果
30
30

九、相关方法

1、== 与 equals 方法
(1)基本介绍
  1. == 即可以判断基本数据类型,又可以判断引用数据类型

  2. == 如果判断基本数据类型,判断的是值是否相等

  3. == 如果判断引用数据类型,判断的是地址是否相等

  4. equals 方法是 Object 类中的方法,只能判断引用数据类型

  5. equals 方法默认判断地址是否相等,子类往往会重写该方法,用于判断内容是否相等(例如 String)

(2)演示
  • EqualsExercise.java
package com.my.intermediate;public class EqualsExercise {public static void main(String[] args) {Person jack = new Person("jack", 10, '男');Person tom = new Person("tom", 10, '男');System.out.println(jack.equals(tom));}
}class Person {private String name;private int age;private char gender;public Person(String name, int age, char gender) {this.name = name;this.age = age;this.gender = gender;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}public char getGender() {return gender;}public void setGender(char gender) {this.gender = gender;}// 重写 Object 的 equals 方法public boolean equals(Object obj) {// 如果比较的两个对象是同一个对象,那么直接返回 trueif (this == obj) {return true;}// 类型判断if (obj instanceof Person) {// 进行向下转型Person person = (Person) obj;return this.name.equals(person.name) && this.age == person.age && this.gender == person.gender;}// 不是 Person 类型,直接返回 falsereturn false;}
}
2、hashCode 方法
(1)基本介绍
  1. hashCode 方法用于返回该对象的哈希码值

  2. hashCode 方法主要是为了提高具有哈希结构的容器的效率

  3. 两个引用,如果指向的是同一个对象,则哈希值肯定一致

  4. 两个引用,如果指向的是不同对象,则哈希值不一致

  5. 哈希值主要是根据地址来计算的,但不能完全将哈希值等价于地址

(2)基本使用
  • HashCodeTest.java
package com.my.intermediate;public class HashCodeTest {public static void main(String[] args) {Person person1 = new Person();Person person2 = new Person();Person person3 = person1;System.out.println(person1.hashCode());System.out.println(person2.hashCode());System.out.println(person3.hashCode());}
}class Person {}
3、toString 方法
(1)基本介绍
  1. toString 方法默认返回:全类名(包名 + 类名) + @ + 哈希值的十六进制

  2. toString 方法的重写:返回对象的属性信息

  3. 当直接输出一个对象时,toString 方法会被默认调用

(2)基本使用
  • ToStringTest.java
package com.my.intermediate;public class ToStringTest {public static void main(String[] args) {Person person = new Person("jack", 20);System.out.println(person.toString());System.out.println(person);}
}class Person {private String name;private int age;public Person(String name, int age) {this.name = name;this.age = age;}@Overridepublic String toString() {return "Person{" +"name='" + name + '\'' +", age=" + age +'}';}
}
4、finelize 方法
(1)基本介绍
  1. 当对象被回收时,系统自动调用该对象的 finelize 方法,子类可以重写该方法,做一些释放资源的操作

  2. 何时被回收:当某个对象没有任何引用时,JVM 会认为该对象是垃圾对象并使用垃圾回收机制销毁该对象,在销毁该对象前,会先调用 finelize 方法

  3. 垃圾回收机制:由系统决定调用,也可以通过调用 System.gc() 主动触发

(2)基本使用
  • FinelizeTest.java
package com.my.intermediate;public class FinelizeTest {public static void main(String[] args) {Car car = new Car("宝马");car = null;System.gc();System.out.println("程序结束了");}
}class Car {private String name;public Car(String name) {this.name = name;}@Overrideprotected void finalize() throws Throwable {System.out.println("销毁了" + name);}
}

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com