面向对象(中级)
1.1 包
命名规则
包的命名
常用的包
一个包下,包含很多的类,java 中常用的包有:
- java.lang.* //lang 包是基本包,默认引入,不需要再引入. 2) java.util.* //util 包,系统提供的工具包, 工具类,使用 Scanner
- java.net.* //网络包,网络开发
- java.awt.* //是做 java 的界面开发,GUI
包的细节
code
import java.util.Arrays; // 表示引入java.util.下面的Arrays类
import java.util.*; // 表示引入java.util.下面的所有类
public class Import01 {
public static void main(String[] args) {
int arr[] = {1,2,-111,3423,11};
Arrays.sort(arr);
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i]+" ");
}
}
}
run
//(1)package 的作用是声明当前类所在的包,
// 需要放在类(或者文件)的最上面,
// 一个类中最多只有一句 package
package package_01;
//(2)import 指令 位置放在 package 的下面,在类定义前面,可以有多句且没有顺序要求
import java.util.Scanner;
import java.util.Arrays;
public class PackageDetail {
public static void main(String[] args) {
}
}
1.2 访问修饰符
基本介绍
java 提供四种访问控制修饰符号,用于控制方法和属性(成员变量)的访问权限(范围):
- 公开级别:用 public 修饰,对外公开
- 受保护级别:用 protected 修饰,对子类和同一个包中的类公开
- 默认级别:没有修饰符号,向同一个包的类公开.
- 私有级别:用 private 修饰,只有类本身可以访问,不对外公开.
案例演示:
run
1.3 面向对象三大特征
面向对象编程有三大特征:封装、继承和多态。
2.1 封装
code
package encapsulation_03;
public class Encapsulation01 {
public static void main(String[] args) {
/*
不能随便查看人的年龄,工资等隐私,并对设置的年龄进行合理的验证。
年龄合理就设置 年龄必须在 1-120 , 工资不能直接查看 ,
name 的长度在 2-6 字符 之间
*/
Person person = new Person();
// person.sal = 200; // private属性 err
person.setName("jack");
person.setAge(18);
person.setSal(3000);
System.out.println(person.showInfo());
// 我们可以将 set 方法写在构造器中,这样仍然可以进行数据的验证
System.out.println("======Tom的信息======");
Person tom = new Person("tom", 30000, 2000);
tom.showInfo();
}
}
class Person {
public String name;
private int age;
private double sal;
public Person() {
}
public Person(String name, int age, double sal) {
// this.name = name;
// this.age = age;
// this.sal = sal;
// 调用set方法对数据进行校验
setName(name);
setAge(age);
setSal(sal);
}
public String getName() {
return name;
}
public void setName(String name) {
if (name.length() >= 2 && name.length() <= 6) {
this.name = name;
} else {
System.out.println("姓名长度不合法");
this.name = "admin";
}
}
public int getAge() {
return age;
}
public void setAge(int age) {
if (age>=1 && age<=120) {
this.age = age;
}else{
System.out.println("年龄不合法");
this.age = 18;
}
}
public double getSal() {
return sal;
}
public void setSal(double sal) {
this.sal = sal;
}
public String showInfo() {
return "姓名 = " + name + " 年龄 = " + age + " 薪水 = " + sal;
}
}
run
code
package encapsulation_03;
public class EncapExercise {
public static void main(String[] args) {
/**
* 创建程序,在其中定义两个类:Account 和 AccountTest 类体会 Java 的封装性。
* Account 类要求具有属性:姓名(长度为 2 位 3 位或 4 位)、余额(必须>20)、
* 密码(必须是六位), 如果不满足,则给出提示信息,并给默认值(程序员自己定)
* 通过 setXxx 的方法给 Account 的属性赋值。
* 在 AccountTest 中测试
*/
Account account = new Account("Test", 2000, "123456");
System.out.println(account.showInfo());
}
}
class Account {
private String name;
private double sal;
private String password;
public Account(String name, double sal, String password) {
// this.name = name;
// this.sal = sal;
// this.password = password;
setName(name);
setSal(sal);
setPassword(password);
}
public String getName() {
return name;
}
public void setName(String name) {
if (name.length() >= 2 && name.length() <= 4) {
this.name = name;
} else {
System.out.println("姓名必须是在(2-4)位");
this.name = "admin";
}
}
public double getSal() {
return sal;
}
public void setSal(double sal) {
if (sal>=20) {
this.sal = sal;
}else {
System.out.println("余额必须是在20元以上");
this.sal = 20;
}
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
if (password.length() == 6) {
this.password = password;
} else {
System.out.println("密码必须是6位");
this.password = "password";
}
}
public String showInfo() {
return "姓名 = " + name + " 密码 = " + password + " 余额 = " + sal;
}
}
run
2.2 继承
继承可以提高代码复用性
继承细节
-
子类继承了所有的属性和方法,非私有的属性和方法可以在子类直接访问, 但是私有属性和方法不能在子类直接访问,要通过父类提供公共的方法去访问
-
子类必须先调用父类的构造器, 完成父类的初始化
-
当创建子类对象时,不管使用子类的哪个构造器,默认情况下总会去调用父类的无参构造器,如果父类没有提供无参构造器,则必须在子类的构造器中用 super 去指定使用父类的哪个构造器完成对父类的初始化工作,否则,编译不会通过
-
如果希望指定去调用父类的某个构造器,则显式的调用一下 : super(参数列表)
-
super 在使用时,必须放在构造器第一行(super 只能在构造器中使用)
-
super() 和 this() 都只能放在构造器第一行,因此这两个方法不能共存在一个构造器
-
java 所有类都是 Object 类的子类, Object 是所有类的基类.
-
父类构造器的调用不限于直接父类!将一直往上追溯直到 Object 类(顶级父类)
-
子类最多只能继承一个父类(指直接继承),即 java 中是单继承机制。
思考:如何让 A 类继承 B 类和 C 类? 【A 继承 B, B 继承 C】 -
不能滥用继承,子类和父类之间必须满足 is-a 的逻辑关系
继承本质
package extends_04;
/**
* 讲解继承的本质
*/
public class ExtendsTheory {
public static void main(String[] args) {
Son son = new Son();//内存的布局
//?-> 这时请大家注意,要按照查找关系来返回信息
//(1) 首先看子类是否有该属性
//(2) 如果子类有这个属性,并且可以访问,则返回信息
//(3) 如果子类没有这个属性,就看父类有没有这个属性(如果父类有该属性,并且可以访问,就返回信息..)
//(4) 如果父类没有就按照(3)的规则,继续找上级父类,直到Object...
System.out.println(son.name);//返回就是大头儿子
//如果想访问GrandPa类的age,是不行的,因为Father类也有age,除非写个方法来间接访问
//System.out.println(son.age);
System.out.println(son.getAge());//返回的就是39
System.out.println(son.hobby);//返回的就是旅游
}
}
class GrandPa { //爷类
String name = "大头爷爷";
String hobby = "旅游";
int age = 200;
}
class Father extends GrandPa {//父类
String name = "大头爸爸";
private int age = 39;
public int getAge() {
return age;
}
}
class Son extends Father { //子类
String name = "大头儿子";
}
run
exercise
package extends_04;
import modifier_02.A;
public class Exercise01 {
public static void main(String[] args) {
B b = new B();
}
}
class AA{
AA(){
System.out.println("a");
}
AA(String name){
System.out.println("a name");
}
}
class B extends AA {
B(){
this("abc");
System.out.println("b");
}
B(String name){
// super() 此题关键
System.out.println("b name");
}
}
run
exercise
package extends_04;
public class Exercise02 {
public static void main(String[] args) {
C c = new C();
}
}
class A {//A类
public A() {
System.out.println("我是A类");
}
}
class BB extends A { //B类,继承A类 //main方法中: C c =new C(); 输出么内容? 3min
public BB() {
System.out.println("我是B类的无参构造");
}
public BB(String name) {
System.out.println(name + "我是B类的有参构造");
}
}
class C extends BB { //C类,继承 B类
public C() {
this("hello");
System.out.println("我是c类的无参构造");
}
public C(String name) {
super("hahah");
System.out.println("我是c类的有参构造");
}
}
run
exercise
package extends_04;
public class Exercise03 {
public static void main(String[] args) {
/*
编写Computer类,包含CPU、内存、硬盘等属性,getDetails方法用于返回Computer的详细信息
编写PC子类,继承Computer类,添加特有属性【品牌brand】
编写Test类,在main方法中创建PC对象,分别给对象中特有的属性赋值,
以及从Computer类继承的属性赋值,并使用方法并打印输出信息
*/
PC pc = new PC("1","2","3","4");
pc.showInfo();
}
}
class Computer {
private String CPU;
private String memory;
private String hardDisk;
public String getDetails() {
return "cpu=" + CPU + " memory=" + memory + " disk=" + hardDisk;
}
public Computer(String CPU, String memory, String hardDisk) {
this.CPU = CPU;
this.memory = memory;
this.hardDisk = hardDisk;
}
}
class PC extends Computer {
private String brand;
public PC(String CPU, String memory, String hardDisk, String brand) {
super(CPU, memory, hardDisk);
this.brand = brand;
}
public void showInfo(){
System.out.println(getDetails()+" brand = "+brand);
}
public void setBrand(String brand){
this.brand = brand;
}
public String getBrand(){
return this.brand;
}
}
run
super
super 代表父类的引用,用于访问父类的属性、方法、构造器
super细节
方法的重写
- 编写一个 Person 类,包括属性/private(name、age),构造器、方法 say(返回自我介绍的字符串)。
- 编写一个 Student 类,继承 Person 类,增加 id、score 属性/private,以及构造器,定义 say 方法(返回自我介绍的信息)。
- 在 main 中,分别创建 Person 和 Student 对象,调用 say 方法输出自我介绍
代码
code
package override_06;
public class OverrideExercise {
public static void main(String[] args) {
// 1) 编写一个 Person 类,包括属性/private(name、age),
// 构造器、方法 say(返回自我介绍的字符串)。
// 2) 编写一个 Student 类,继承 Person 类,增加 id、score 属性/private,
// 以及构造器,定义 say 方法(返回自我介绍的信息)。
// 3) 在 main 中,分别创建 Person 和 Student 对象,调用 say 方法输出自我介绍
Person person = new Person("小明",18);
System.out.println(person.say());
System.out.println("======");
Student student = new Student("Jack",20,100,95);
System.out.println(student.say());
}
}
class Person{
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public String say(){
return "我的名字是:"+name+" 年龄是:"+age;
}
}
class Student extends Person{
private int id;
private double score;
public Student(String name, int age,int id,double score){
super(name,age);
this.id = id;
this.score = score;
}
@Override
public String say(){
// 要加super来调用父类的say方法,否则调用的是本类的say方法
return super.say()+" 我的学号:"+id+" 分数是:"+score;
}
}
run
2.3 多态
使用传统的方法来解决(private 属性)
传统的方法带来的问题是什么? 如何解决?
问题是: 代码的复用性不高,而且不利于代码维护
解决方案: 引出我们要讲解的多态
package poly_07;
public class PolyObject {
public static void main(String[] args) {
//体验对象多态特点
//animal 编译类型就是 Animal , 运行类型 Dog
Animal animal = new Dog();
//因为运行时 , 执行到改行时,animal 运行类型是 Dog,所以 cry 就是 Dog 的 cry
animal.cry();
animal = new Cat();
//animal 编译类型 Animal,运行类型就是 Cat
animal.cry();
}
}
class Animal{
public void cry(){
System.out.println("动物在叫...");
}
}
class Dog extends Animal {
public void cry(){
System.out.println("狗在叫...");
}
}
class Cat extends Animal{
public void cry(){
System.out.println("猫在叫...");
}
}
run
向上转型与向下转型
package poly_07.PolyDetail;
public class PolyDetail {
public static void main(String[] args) {
//向上转型: 父类的引用指向了子类的对象
//语法:父类类型引用名 = new 子类类型();
Animal animal = new Cat();
Object obj = new Cat();// 可以 Object 也是 Cat的父类
//向上转型调用方法的规则如下:
//(1)可以调用父类中的所有成员(需遵守访问权限)
//animal.m1(); // err
//(2)但是不能调用子类的特有的成员
//System.out.println(animal.test); // animal中无test , 所以err
//(3)因为在编译阶段,能调用哪些成员,是由编译类型来决定的
//animal.catchMouse();错误 // animal中无catchMouse() , 所以err
//(4)最终运行效果看子类(运行类型)的具体实现, 即调用方法时,按照从子类(运行类型)开始查找方法
//,然后调用,规则我前面我们讲的方法调用规则一致。
animal.eat();//猫吃鱼..
animal.run();//跑
animal.show();//hello,你好
animal.sleep();//睡
//可以调用Cat的 catchMouse方法
//多态的向下转型
//(1)语法:子类类型 引用名 =(子类类型)父类引用;
//问一个问题? cat 的编译类型 Cat,运行类型是 Cat
Cat cat = (Cat) animal;
cat.catchMouse();//猫抓老鼠
//cat.m1 // 是私有的
//(2)要求父类的引用必须指向的是当前目标类型的对象
//Dog dog = (Dog) animal; //err
}
}
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,你好");
}
private void m1(){
System.out.println("Animal 私有方法");
}
}
class Cat extends Animal {
public String test;
public void eat() {//方法重写
System.out.println("猫吃鱼");
}
public void catchMouse() {//Cat特有方法
System.out.println("猫抓老鼠");
}
}
class Dog extends Animal {//Dog是Animal的子类
}
code
package poly_07.PolyDetail;
public class PolyDetail02 {
public static void main(String[] args) {
//属性没有重写之说!属性的值看编译类型
Base base = new Sub();//向上转型
System.out.println(base.count);// ? 看编译类型 10
Sub sub = new Sub();
System.out.println(sub.count);//? 20
}
}
class Base { //父类
int count = 10;//属性
}
class Sub extends Base {//子类
int count = 20;//属性
}
run
code
package poly_07.PolyDetail;
public class PolyDetail03 {
public static void main(String[] args) {
BB bb = new BB();
System.out.println(bb instanceof BB);// true
System.out.println(bb instanceof AA);// true
//aa 编译类型 AA, 运行类型是BB
//BB是AA子类
AA aa = new BB();
System.out.println(aa instanceof AA);
System.out.println(aa instanceof BB);
Object obj = new Object();
System.out.println(obj instanceof AA);//false
String str = "hello";
//System.out.println(str instanceof AA); //err
System.out.println(str instanceof Object);//true
}
}
class AA {} //父类
class BB extends AA {}//子类
run
exercise
求输出结果
package dynamicbinding_08;
public class DynamicBinding {
public static void main(String[] args) {
//a 的编译类型 A, 运行类型 B
A a = new B();//向上转型
System.out.println(a.sum());//?
System.out.println(a.sum1());//?
}
}
class A {//父类
public int i = 10;
//动态绑定机制:
public int sum() {//父类sum()
return getI() + 10;//20 + 10
}
public int sum1() {//父类sum1()
return i + 10;//10 + 10
}
public int getI() {//父类getI
return i;
}
}
class B extends A {//子类
public int i = 20;
public int sum() {
return i + 20;
}
public int getI() {//子类getI()
return i;
}
public int sum1() {
return i + 10;
}
}
run
动态绑定机制
package dynamicbinding_08;
public class DynamicBinding {
public static void main(String[] args) {
//a 的编译类型 A, 运行类型 B
A a = new B();//向上转型
System.out.println(a.sum());//?40 -> 30
System.out.println(a.sum1());//?30-> 20
}
}
class A {//父类
public int i = 10;
//动态绑定机制:
public int sum() {//父类sum()
return getI() + 10;//20 + 10
}
public int sum1() {//父类sum1()
return i + 10;//10 + 10
}
public int getI() {//父类getI
return i;
}
}
class B extends A {//子类
public int i = 20;
// public int sum() {
// return i + 20;
// }
public int getI() {//子类getI()
return i;
}
// public int sum1() {
// return i + 10;
// }
}
run
先找A对象是否有sum()方法,没有直接报错,然后找运行类型B对象,找B的sum1()方法,没有的话,根据继承机制找到A的sum()方法,根据动态绑定进制,运行类型是B,直接调用B对象的getI()方法
先找A对象是否有sum1()方法,没有直接报错,然后找运行类型B对象,找B的sum1()方法,没有的话,根据继承机制找到A的sum1()方法,根据动态绑定进制,属性不具备动态绑定机制,直接找到本类的属性
多态数组
package polyarr_09;
public class PolyArray {
public static void main(String[] args) {
Person[] persons = new Person[3];
persons[0] = new Person("jack", 40);
persons[1] = new Student("tom", 18, 60);
persons[2] = new Teacher("scott", 38, 6000);
// 类型判断 + 向下转型
// person[i] 编译类型是 Person ,运行类型是是根据实际情况有 JVM 来判
for (int i = 0; i < persons.length; i++) {
//动态绑定机制
System.out.println(persons[i].say());
if (persons[i] instanceof Student) {
Student student = (Student) persons[i];
student.study();
} else if (persons[i] instanceof Teacher) {
((Teacher) persons[i]).teach();
}
}
}
}
class Person {
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public String say() {
return name + " " + 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 Person {
private double score;
public Student(String name, int age, double score) {
super(name, age);
this.score = score;
}
@Override
public String say() {
return super.say() + " " + score;
}
public void study() {
System.out.println(getName() + " 正在学Java...");
}
}
class Teacher extends Person {
private double salary;
public Teacher(String name, int age, double salary) {
super(name, age);
this.salary = salary;
}
@Override
public String say() {
return super.say() + " " + salary;
}
public void teach() {
System.out.println(getName() + " 正在上课...");
}
}
run
code
package polyarr_09;
/**
* 多态参数
*/
public class PolyParameter {
// 获取年薪
public void showEmpAnnual(Employee e) {
System.out.println(e.getAnnual());
}
public static void main(String[] args) {
PolyParameter polyParameter = new PolyParameter();
Employee[] employee = new Employee[3];
employee[0] = new Employee("Jack", 3000);
employee[1] = new Worker("Tom", 3500);
employee[2] = new Manager("Snow", 100000, 999);
for (int i = 0; i < employee.length; i++) {
polyParameter.showEmpAnnual(employee[i]);
if (employee[i] instanceof Worker) {
((Worker) employee[i]).work();
} else if (employee[i] instanceof Manager) {
((Manager) employee[i]).manage();
}
}
}
}
class Employee {
private String name;
private double sal;
public Employee(String name, double sal) {
this.name = name;
this.sal = sal;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAnnual() {
return getName()+"的薪水:"+sal * 12;
}
}
class Worker extends Employee {
public Worker(String name, double sal) {
super(name, sal);
}
public void work() {
System.out.println("员工正在工作...");
}
@Override
public String getAnnual() {
return "员工的薪水:" + super.getAnnual();
}
}
class Manager extends Employee {
private double bonus;
public Manager(String name, double sal, double bonus) {
super(name, sal);
this.bonus = bonus;
}
public void manage() {
System.out.println("经理正在管理...");
}
@Override
public String getAnnual() {
return "经理的薪水:" + super.getAnnual() + "奖金:" + bonus;
}
}
3.1equals()
package equals_10;
public class Equals01 {
public static void main(String[] args) {
A a = new A();
A b = a;
A c = b;
System.out.println(a == c);//true
System.out.println(b == c);//true
B bObj = a; // 向上转型
System.out.println(bObj == c);//true
int num1 = 10;
double num2 = 10.0;
System.out.println(num1 == num2);//基本数据类型,判断值是否相等 true
//equals 方法,源码怎么查看.
//把光标放在equals方法,直接输入ctrl+b
//如果你使用不了. 自己配置. 即可使用.
/*
//带大家看看Jdk的源码 String类的 equals方法
//把Object的equals方法重写了,变成了比较两个字符串值是否相同
public boolean equals(Object anObject) {
if (this == anObject) {//如果是同一个对象
return true;//返回true
}
if (anObject instanceof String) {//判断类型 运行类型
String anotherString = (String)anObject;//向下转型
int n = value.length;
if (n == anotherString.value.length) {//如果长度相同
char v1[] = value;
char v2[] = anotherString.value;
int i = 0;
while (n-- != 0) {//然后一个一个的比较字符
if (v1[i] != v2[i])
return false;
i++;
}
return true;//如果两个字符串的所有字符都相等,则返回true
}
}
return false;//如果比较的不是字符串,则直接返回false
}
*/
"hello".equals("abc");
//看看Object类的 equals 是
/*
//即Object 的equals 方法默认就是比较对象地址是否相同
//也就是判断两个对象是不是同一个对象.
public boolean equals(Object obj) {
return (this == obj);
}
*/
/*
//从源码可以看到 Integer 也重写了Object的equals方法,
//变成了判断两个值是否相同
public boolean equals(Object obj) {
if (obj instanceof Integer) {
return value == ((Integer)obj).intValue();
}
return false;
}
*/
Integer integer1 = new Integer(1000);
Integer integer2 = new Integer(1000);
System.out.println(integer1 == integer2);//false 比较地址
System.out.println(integer1.equals(integer2));//true
String str1 = new String("wyt");
String str2 = new String("wyt");
System.out.println(str1 == str2);//false
System.out.println(str1.equals(str2));//true
}
}
class B {}
class A extends B {}
run
重写equals()
package equals_10;
public class EqualsExercise01 {
public static void main(String[] args) {
Person person1 = new Person("jack", 10, '男');
Person person2 = new Person("jack", 20, '男');
System.out.println(person1.equals(person2));//假 判断两个对象是否相同
System.out.println(person1 == person2);
}
}
//判断两个Person对象的内容是否相等,
//如果两个Person对象的各个属性值都一样,则返回true,反之false
class Person{ //extends Object
private String name;
private int age;
private char gender;
// //重写Object 的 equals方法
// public boolean equals(Object obj) {
// //判断如果比较的两个对象是同一个对象,则直接返回true
// if(this == obj) {
// return true;
// }
// //类型判断
// if(obj instanceof Person) {//是Person,我们才比较
//
// //进行 向下转型, 因为我需要得到obj的 各个属性
// Person p = (Person)obj;
// return this.name.equals(p.name) && this.age == p.age && this.gender == p.gender;
// }
// //如果不是Person ,则直接返回false
// return false;
//
// }
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;
}
}
true
求运行结果
package equals_10;
public class EqualsExercise02 {
public static void main(String[] args) {
Person_ p1 = new Person_();
p1.name = "wyt";
Person_ p2 = new Person_();
p2.name = "wyt";
System.out.println(p1 == p2); //False
System.out.println(p1.name.equals(p2.name));//T
System.out.println(p1.equals(p2));//False Object的equals()方法比较的是地址
String s1 = new String("asdf");
String s2 = new String("asdf");
System.out.println(s1.equals(s2));//T
System.out.println(s1 == s2); //F
}
}
class Person_ {//类
public String name;
}
run
exercise
3.2hashCode()
- 提高具有哈希结构的容器的效率!
- 两个引用,如果指向的是同一个对象,则哈希值肯定是一样的!
- 两个引用,如果指向的是不同对象,则哈希值是不一样的
- 哈希值主要根据地址号来的!, 不能完全将哈希值等价于地址。
package hashcode_11;
public class HashCode {
public static void main(String[] args) {
//hashCode()是通过将该对象的内部地址转换成一个整数
AA aa = new AA();
AA aa2 = new AA();
AA aa3 = aa;
System.out.println("aa.hashCode()=" + aa.hashCode());
System.out.println("aa2.hashCode()=" + aa2.hashCode());
System.out.println("aa3.hashCode()=" + aa3.hashCode());
}
}
class AA {
}
3.3toString()
- 基本介绍
默认返回:全类名+@+哈希值的十六进制,【查看 Object 的 toString 方法】
子类往往重写 toString 方法,用于返回对象的属性信息- 重写 toString 方法,打印对象或拼接对象时,都会自动调用该对象的 toString 形式.
- 当直接输出一个对象时,toString 方法会被默认的调用, 比如 System.out.println(monster); 就会默认调用
monster.toString()
package tostring_12;
public class ToString {
public static void main(String[] args) {
/*
Object的toString() 源码
(1)getClass().getName() 类的全类名(包名+类名 )
(2)Integer.toHexString(hashCode()) 将对象的hashCode值转成16进制字符串
public String toString() {
return getClass().getName() + "@" + Integer.toHexString(hashCode());
}
*/
Monster monster = new Monster("小妖怪", "巡山的", 1000);
System.out.println(monster.toString() + " hashcode=" + monster.hashCode());
System.out.println("==当直接输出一个对象时,toString 方法会被默认的调用==");
System.out.println(monster); //等价 monster.toString()
}
}
class Monster {
private String name;
private String job;
private double sal;
public Monster(String name, String job, double sal) {
this.name = name;
this.job = job;
this.sal = sal;
}
//重写toString方法, 输出对象的属性
//使用快捷键即可 alt+insert -> toString
@Override
public String toString() { //重写后,一般是把对象的属性值输出,当然程序员也可以自己定制
return "Monster{" +
"name='" + name + '\'' +
", job='" + job + '\'' +
", sal=" + sal +
'}';
}
@Override
protected void finalize() throws Throwable {
System.out.println("fin..");
}
}
3.4finalize()
- 当对象被回收时,系统自动调用该对象的 finalize 方法。子类可以重写该方法,做一些释放资源的操作
- 什么时候被回收:当某个对象没有任何引用时,则 jvm 就认为这个对象是一个垃圾对象,就会使用垃圾回收机制来
销毁该对象,在销毁该对象前,会先调用 finalize 方法。- 垃圾回收机制的调用,是由系统来决定(即有自己的 GC 算法), 也可以通过 System.gc() 主动触发垃圾回收机制,测
试
package finalize_13;
//演示 Finalize的用法
public class Finalize {
public static void main(String[] args) {
Car bmw = new Car("宝马");
//这时 car对象就是一个垃圾,垃圾回收器就会回收(销毁)对象, 在销毁对象前,会调用该对象的finalize方法
//,程序员就可以在 finalize中,写自己的业务逻辑代码(比如释放资源:数据库连接,或者打开文件..)
//,如果程序员不重写 finalize,那么就会调用 Object类的 finalize, 即默认处理
//,如果程序员重写了finalize, 就可以实现自己的逻辑
bmw = null;
System.gc();//主动调用垃圾回收器
System.out.println("程序退出了....");
}
}
class Car {
private String name;
//属性, 资源。。
public Car(String name) {
this.name = name;
}
//重写finalize
@Override
protected void finalize() throws Throwable {
System.out.println("我们销毁 汽车" + name );
System.out.println("释放了某些资源...");
}
}
4.1本章作业
public class HomeWork01 {
public static void main(String[] args) {
Person p1 = new Person("jack",18,"学生");
Person p2 = new Person("mary",29,"护士");
Person p3 = new Person("scott",41,"老师");
Person persons[] = new Person[3];
Person temp = null;
persons[0] = p1;
persons[1] = p2;
persons[2] = p3;
for (int i = 0 ; i < persons.length-1 ;i++){
for (int j = 0 ; j< persons.length-1-i ;j++){
if (persons[j].getAge() < persons[j+1].getAge()){
temp = persons[j];
persons[j] = persons[j+1];
persons[j+1] = temp;
}
}
}
for (int i = 0 ; i< persons.length ; i++){
System.out.println(persons[i]);
}
}
}
class Person{
private String name;
private int age;
private String job;
public Person(String name, int age, String job) {
this.name = name;
this.age = age;
this.job = job;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
public String getJob() {
return job;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
", job='" + job + '\'' +
'}';
}
}
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 introduce(){
return name+" "+age+" "+post+" "+sal+" ";
}
}
class Professor extends Teacher{
private double grade;
public Professor(String name, int age, String post, double sal, double grade) {
super(name, age, post, sal);
this.grade = grade;
}
@Override
public String introduce(){
return super.introduce()+grade;
}
}
public class HomeWork03 {
public static void main(String[] args) {
Employee jack = new Employee("jack", 3000, 10);
jack.printSal();
Manager manager = new Manager("tom",4000,30);
manager.printSal();
}
}
class Employee{
private String name;
private double sal;
private int day;
public Employee(String name, double sal, int day) {
this.name = name;
this.sal = sal;
this.day = day;
}
public void printSal(){
System.out.println(name+" "+sal+" "+day);
}
public String getName() {
return name;
}
public double getSal() {
return sal;
}
public int getDay() {
return day;
}
}
class Manager extends Employee{
public Manager(String name, double sal, int day) {
super(name, sal, day);
}
@Override
public void printSal() {
System.out.println(getName()+" "+(1000+getSal()*getDay()*1.2));
}
}
package homework_17;
public class HomeWork07 {
public static void main(String[] args) {
Doctor d1 = new Doctor("jack", 18, "医生", '男', 1200);
Doctor d2 = new Doctor("jack", 18, "医生", '男', 1200);
System.out.println(d1.equals(d2));
}
}
class Doctor {
private String name;
private int age;
private String job;
private char gender;
private double sal;
public Doctor(String name, int age, String job, char gender, double sal) {
this.name = name;
this.age = age;
this.job = job;
this.gender = gender;
this.sal = sal;
}
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (!(obj instanceof Doctor)) {
return false;
}
Doctor d = (Doctor) obj;
return this.name.equals(d.name) && this.age == d.age && this.gender == d.gender && this.sal == d.sal && this.job == d.job;
}
}
public class HomeWork09 {
public void show(Person_ p) {
if (p instanceof Student) {
System.out.println(((Student) p).study());
} else if (p instanceof Teacher_) {
System.out.println(((Teacher_) p).teach());
}else {
;
}
}
public static void main(String[] args) {
Person_[] persons = new Person_[4];
// 向上转型
persons[0] = new Student("小明", '男', 18, "011");
persons[1] = new Teacher_("mary", '女', 39, 15);
persons[2] = new Student("小刚", '女', 28, "012");
persons[3] = new Teacher_("jack", '男', 49, 13);
Person_ tmp = null;
for (int i = 0; i < persons.length - 1; i++) {
for (int j = 0; j < persons.length - 1 - i; j++) {
if (persons[j].getAge() < persons[j + 1].getAge()) {
tmp = persons[j];
persons[j] = persons[j + 1];
persons[j + 1] = tmp;
}
}
}
for (int i = 0; i < persons.length; i++) {
System.out.println(persons[i]);
if (i < persons.length - 1) {
System.out.println("==============================");
}
}
HomeWork09 homeWork09 = new HomeWork09();
for (int i = 0; i < persons.length; i++) {
homeWork09.show(persons[i]);
}
}
}
class Person_ {
private String name;
private char sex;
private int age;
public Person_(String name, char sex, int age) {
this.name = name;
this.sex = sex;
this.age = age;
}
public String play() {
return name + "爱玩";
}
public int getAge() {
return age;
}
@Override
public String toString() {
return "姓名:" + name + "\n" +
"年龄:" + age + "\n" +
"性别:" + sex + "\n";
}
}
class Student extends Person_ {
private String stu_id;
public Student(String name, char sex, int age, String stu_id) {
super(name, sex, age);
this.stu_id = stu_id;
}
public String study() {
return "我会好好学习";
}
@Override
public String play() {
return super.play() + "足球";
}
@Override
public String toString() {
return "学生的信息:\n" + super.toString() + "学号:" + stu_id + "\n" + study() + "\n" + play();
}
}
class Teacher_ extends Person_ {
private int work_age;
public Teacher_(String name, char sex, int age, int work_age) {
super(name, sex, age);
this.work_age = work_age;
}
@Override
public String play() {
return super.play() + "象棋";
}
public String teach() {
return "我一定好好教书";
}
public String toString() {
return "老师的信息:\n" + super.toString() + "工龄:" + work_age + "\n" + teach() + "\n" + play();
}
}
public class HomeWork10 {
public static void main(String[] args) {
AAA obj = new BBB();//向上转型
AAA b1 = obj;
System.out.println("obj的运行类型=" + obj.getClass());//BBB
obj = new CCC();//向上转型
System.out.println("obj的运行类型=" + obj.getClass());//CCC
obj = b1;
System.out.println("obj的运行类型=" + obj.getClass());//BBB
}
}
class AAA {//超类
}
class BBB extends AAA {//父类
}
class CCC extends BBB {//子类
}