==> 视频链接
==> 视频链接
File => Settings => Editor => Live Templates ,这里可以查看有哪些模板快捷键,也可以自定义模板,可以很好提高开发效率~
package com.xjs;
说明:
包的本质:实际上就是创建不同的文件夹/目录来保存文件!
一个包下,包含很多的类,java 中常用的包有:
java.lang.*
, lang 包是基本包,默认引入,不需要再引入java.util.*
,util 包,系统提供的工具包,工具类,使用 Scannerjava.net.*
,网络包,网络开发java.awt.*
,是做 java 的界面开发,GUIimport 包;
import java.util.Scanner;
就只是引入一个类Scannerimport java.util.* ;
表示将java.util 包所有的类都引入package com.hspedu.pkg;
import java.util.Arrays;
//注意:
//建议:我们需要使用到哪个类,就导入哪个类即可,不建议使用 *导入
//import java.util.Scanner; //表示只会引入java.util 包下的 Scanner
//import java.util.*;//表示将java.util 包下的所有类都引入(导入)
public class Import01 {
public static void main(String[] args) {
//使用系统提供 Arrays 完成 数组排序
int[] arr = {-1, 20, 2, 13, 3};
//比如对其进行排序
//传统方法是,自己编写排序(冒泡)
//系统是提供了相关的类,可以方便完成 Arrays
Arrays.sort(arr);
//输出排序结果
for (int i = 0; i < arr.length ; i++) {
System.out.print(arr[i] + "\t");
}
}
}
//package的作用是声明当前类所在的包,需要放在类(或者文件)的最上面,
// 一个类中最多只有一句package
package com.hspedu.pkg;
//import指令 位置放在package的下面,在类定义前面,可以有多句且没有顺序要求
import java.util.Scanner;
import java.util.Arrays;
//...
//类定义
public class PkgDetail {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int[] arr = {0, -1, 1};
Arrays.sort(args);
}
}
java 提供四种访问控制修饰符号,用于控制 方法 和 属性(成员变量) 的访问权限(范围)
==> 视频链接
面向对象编程有三大特征:封装、继承 和 多态
public void setXxx(类型 参数名){//Xxx 表示某个属性
//加入数据验证的业务逻辑
属性 = 参数名;
}
public void getXxx(类型 参数名){//Xxx 表示某个属性
//权限判断
return xx;
}
请大家看一个小程序:
不能随便查看人的年龄,工资等隐私,并对设置的年龄进行合理的验证。年龄合理就设置,否则给默认年龄,必须在 1-120, 年龄, 工资不能直接查看 , name的长度在 2-6字符之间
package com.hspedu.encap;
public class Encapsulation01 {
public static void main(String[] args) {
//如果要使用快捷键alt+r, 需要先配置主类
//第一次,我们使用鼠标点击形式运算程序,后面就可以用
Person person = new Person();
person.setName("韩顺平");
person.setAge(30);
person.setSalary(30000);
System.out.println(person.info());
System.out.println(person.getSalary());
//如果我们自己使用构造器指定属性
Person smith = new Person("smith", 80, 50000);
System.out.println("====smith的信息======");
System.out.println(smith.info());
}
}
/*
那么在java中如何实现这种类似的控制呢?
请大家看一个小程序
不能随便查看人的年龄,工资等隐私,并对设置的年龄进行合理的验证。年龄合理就设置,否则给默认年龄, 必须在 1-120, 年龄, 工资不能直接查看 , name的长度在 2-6字符 之间
*/
class Person {
public String name; //名字公开
private int age; //age 私有化
private double salary; //..
public void say(int n,String name) {
}
//构造器 alt+insert
public Person() {
}
//有三个属性的构造器
public Person(String name, int age, double salary) {
// this.name = name;
// this.age = age;
// this.salary = salary;
//我们可以将set方法写在构造器中,这样仍然可以验证
setName(name);
setAge(age);
setSalary(salary);
}
//自己写setXxx 和 getXxx 太慢,我们使用快捷键alt + insert
//然后根据要求来完善我们的代码.
public String getName() {
return name;
}
public void setName(String name) {
//加入对数据的校验,相当于增加了业务逻辑
if(name.length() >= 2 && name.length() <=6 ) {
this.name = name;
}else {
System.out.println("名字的长度不对,需要(2-6)个字符,默认名字");
this.name = "无名人";
}
}
public int getAge() {
return age;
}
public void setAge(int age) {
//判断
if(age >= 1 && age <= 120) {//如果是合理范围
this.age = age;
} else {
System.out.println("你设置年龄不对,需要在 (1-120), 给默认年龄18 ");
this.age = 18;//给一个默认年龄
}
}
public double getSalary() {
//可以这里增加对当前对象的权限判断
return salary;
}
public void setSalary(double salary) {
this.salary = salary;
}
//写一个方法,返回属性信息
public String info() {
return "信息为 name=" + name + " age=" + age + " 薪水=" + salary;
}
}
看案例:
//有三个属性的构造器
public Person(String name, int age, double salary) {
// this.name = name;
// this.age = age;
// this.salary = salary;
//我们可以将 set 方法写在构造器中,这样仍然可以验证
setName(name);
setAge(age);
setSalary(salary);
}
创建程序,在其中定义两个类:Account和AccountTest类体会Java的封装性
package com.hspedu.encap;
/**
* 创建程序,在其中定义两个类:Account和AccountTest类体会Java的封装性。
* Account类要求具有属性:姓名(长度为2位3位或4位)、余额(必须>20)、
* 密码(必须是六位), 如果不满足,则给出提示信息,并给默认值(程序员自己定)
* 通过setXxx的方法给Account 的属性赋值。
* 在AccountTest中测试
*/
public class Account {
//为了封装,将3个属性设置为private
private String name;
private double balance;
private String pwd;
//提供两个构造器
public Account() {
}
public Account(String name, double balance, String pwd) {
this.setName(name);
this.setBalance(balance);
this.setPwd(pwd);
}
public String getName() {
return name;
}
//姓名(长度为2位3位或4位)
public void setName(String name) {
if (name.length() >= 2 && name.length() <= 4) {
this.name = name;
} else {
System.out.println("姓名要求(长度为2位3位或4位),默认值 无名");
this.name = "无名";
}
}
public double getBalance() {
return balance;
}
//余额(必须>20)
public void setBalance(double balance) {
if (balance > 20) {
this.balance = balance;
} else {
System.out.println("余额(必须>20) 默认为0");
}
}
public String getPwd() {
return pwd;
}
//密码(必须是六位)
public void setPwd(String pwd) {
if (pwd.length() == 6) {
this.pwd = pwd;
} else {
System.out.println("密码(必须是六位)默认密码为 000000");
this.pwd = "000000";
}
}
//显示账号信息
public void showInfo() {
//可以增加权限的校验
System.out.println("账号信息 name=" + name + " 余额=" + balance + " 密码" + pwd);
// if() {
// System.out.println("账号信息 name=" + name + " 余额=" + balance + " 密码");
// }else{
// System.out.println("你无权查看...");
// }
}
}
package com.hspedu.encap;
public class TestAccount {
public static void main(String[] args) {
//创建Account
Account account = new Account();
account.setName("jack");
account.setBalance(60);
account.setPwd("123456");
account.showInfo();
}
}
==> 视频链接
package com.hspedu.extend_;
public class Extends01 {
public static void main(String[] args) {
Pupil pupil = new Pupil();
pupil.name = "银角大王";
pupil.age = 10;
pupil.testing();
pupil.setScore(60);
pupil.showInfo();
System.out.println("=======");
Graduate graduate = new Graduate();
graduate.name = "金角大王";
graduate.age = 22;
graduate.testing();
graduate.setScore(100);
graduate.showInfo();
}
}
class 子类 extends 父类 {
//代码...
}
package com.hspedu.extend_.improve_;
import com.hspedu.extend_.Graduate;
import com.hspedu.extend_.Pupil;
public class Extends01 {
public static void main(String[] args) {
com.hspedu.extend_.Pupil pupil = new Pupil();
pupil.name = "银角大王~";
pupil.age = 11;
pupil.testing();
pupil.setScore(50);
pupil.showInfo();
System.out.println("=======");
com.hspedu.extend_.Graduate graduate = new Graduate();
graduate.name = "金角大王~";
graduate.age = 23;
graduate.testing();
graduate.setScore(80);
graduate.showInfo();
}
}
package com.hspedu.extend_.improve_;
//父类,是Pupil 和 Graduate的父类
public class Student {
//共有属性
public String name;
public int age;
private double score;//成绩
//共有的方法
public void setScore(double score) {
this.score = score;
}
public void showInfo() {
System.out.println("学生名 " + name + " 年龄 " + age + " 成绩 " + score);
}
}
package com.hspedu.extend_.improve_;
//让Pupil 继承 Student类
public class Pupil extends Student {
public void testing() {
System.out.println("小学生 " + name + " 正在考小学数学..");
}
}
package com.hspedu.extend_.improve_;
public class Graduate extends Student {
public void testing() {//和Pupil不一样
System.out.println("大学生 " + name + " 正在考大学数学..");
}
}
==> 视频链接
super(参数列表)
super()
和 this()
都只能放在构造器第一行,因此这两个方法不能共存在一个构造器package com.hspedu.extend_;
public class ExtendsDetail {
public static void main(String[] args) {
// System.out.println("===第1个对象====");
// Sub sub = new Sub(); //创建了子类对象 sub
// System.out.println("===第2个对象====");
// Sub sub2 = new Sub("jack"); //创建了子类对象 sub2
System.out.println("===第3对象====");
Sub sub3 = new Sub("king", 10); //创建了子类对象 sub2
//sub.sayOk();
}
}
package com.hspedu.extend_;
public class Base extends TopBase { //父类
//4个属性
public int n1 = 100;
protected int n2 = 200;
int n3 = 300;
private int n4 = 400;
public Base() { //无参构造器
System.out.println("父类Base()构造器被调用....");
}
public Base(String name, int age) {//有参构造器
//默认super()
System.out.println("父类Base(String name, int age)构造器被调用....");
}
public Base(String name) {//有参构造器
System.out.println("父类Base(String name)构造器被调用....");
}
//父类提供一个public的方法,返回了n4
public int getN4() {
return n4;
}
public void test100() {
System.out.println("test100");
}
protected void test200() {
System.out.println("test200");
}
void test300() {
System.out.println("test300");
}
private void test400() {
System.out.println("test400");
}
//call
public void callTest400() {
test400();
}
}
package com.hspedu.extend_;
import java.util.Arrays;
//输入ctrl + H 可以看到类的继承关系
public class Sub extends Base { //子类
public Sub(String name, int age) {
//1. 要调用父类的无参构造器, 如下或者 什么都不写,默认就是调用super()
//super();//父类的无参构造器
//2. 要调用父类的 Base(String name) 构造器
//super("hsp");
//3. 要调用父类的 Base(String name, int age) 构造器
super("king", 20);
//细节: super在使用时,必须放在构造器第一行
//细节: super() 和 this() 都只能放在构造器第一行,因此这两个方法不能共存在一个构造器
//this() 不能再使用了
System.out.println("子类Sub(String name, int age)构造器被调用....");
}
public Sub() {//无参构造器
//super(); //默认调用父类的无参构造器
super("smith", 10);
System.out.println("子类Sub()构造器被调用....");
}
//当创建子类对象时,不管使用子类的哪个构造器,默认情况下总会去调用父类的无参构造器
public Sub(String name) {
super("tom", 30);
//do nothing...
System.out.println("子类Sub(String name)构造器被调用....");
}
public void sayOk() {//子类方法
//非私有的属性和方法可以在子类直接访问
//但是私有属性和方法不能在子类直接访问
System.out.println(n1 + " " + n2 + " " + n3);
test100();
test200();
test300();
//test400();错误
//要通过父类提供公共的方法去访问
System.out.println("n4=" + getN4());
callTest400();//
}
}
==> 视频链接
我们看一个案例,来分析一下,当子类继承父类,创建子类对象时,内存中到底发生了什么? 特别提示:当子类对象创建好后,建立查找的关系
package com.hspedu.extend_;
/**
* 继承的本质
*/
public class ExtendsTheory {
public static void main(String[] args) {
Son son = new Son();//内存的布局
//?-> 这时请大家注意,要按照查找关系来返回信息
//(1) 首先看子类是否有该属性
//(2) 如果子类有这个属性,并且可以访问,则返回信息
//(3) 如果子类没有这个属性,就看父类有没有这个属性(如果父类有该属性,并且可以访问,就返回信息..)
//(4) 如果父类没有就按照(3)的规则,继续找上级父类,直到Object...
System.out.println(son.name);//返回就是大头儿子
//System.out.println(son.age);//返回的就是39
//System.out.println(son.getAge());//返回的就是39
System.out.println(son.hobby);//返回的就是旅游
}
}
class GrandPa { //爷类
String name = "大头爷爷";
String hobby = "旅游";
}
class Father extends GrandPa {//父类
String name = "大头爸爸";
private int age = 39;
public int getAge() {
return age;
}
}
class Son extends Father { //子类
String name = "大头儿子";
}
子类创建的内存布局:
解读上图:
子类找方法时 (如 cal()
和 this.cal()
),顺序是:
cannot access
如果查找方法的过程中,没有找到,则提示方法不存在B b = new B();
会输出什么?class A {
A() {
System.out.println("a");
}
A(String name) {
System.out.println("a name");
}
}
class B extends A {
B() {
this("abc"); //super() 和 this() 都只能放在构造器第一行,因此这两个方法不能共存在一个构造器
System.out.println("b");
}
B(String name) {
System.out.println("b name");//分析这里有默认的 super();
}
}
//main方法中:B b = new B(); 会输出什么?
a , b name , b
package com.hspedu.extend_.exercise;
public class ExtendsExercise02 {
public static void main(String[] args) {
C c = new C();
}
}
class A {//A类
public A() {
System.out.println("我是A类");
}
}
class B extends A { //B类,继承A类 //main方法中: C c =new C(); 输出么内容? 3min
public B() {
System.out.println("我是B类的无参构造");
}
public B(String name) {
System.out.println(name + "我是B类的有参构造");
}
}
class C extends B { //C类,继承 B类
public C() {
this("hello");
System.out.println("我是c类的无参构造");
}
public C(String name) {
super("hahah");
System.out.println("我是c类的有参构造");
}
}
----运行结果如下----
我是A类
hahah我是B类的有参构造
我是c类的有参构造
我是c类的无参构造
案例 3 ,按如下要求编写代码
package com.hspedu.extend_.exercise;
//编写Computer类,包含CPU、内存、硬盘等属性,getDetails方法用于返回Computer的详细信息
public class Computer {
private String cpu;
private int memory;
private int disk;
public Computer(String cpu, int memory, int disk) {
this.cpu = cpu;
this.memory = memory;
this.disk = disk;
}
//返回Computer信息
public String getDetails() {
return "cpu=" + cpu + " memory=" + memory + " disk=" + disk;
}
public String getCpu() {
return cpu;
}
public void setCpu(String cpu) {
this.cpu = cpu;
}
public int getMemory() {
return memory;
}
public void setMemory(int memory) {
this.memory = memory;
}
public int getDisk() {
return disk;
}
public void setDisk(int disk) {
this.disk = disk;
}
}
package com.hspedu.extend_.exercise;
//编写PC子类,继承Computer类,添加特有属性【品牌brand】
public class PC extends Computer{
private String brand;
//这里IDEA 根据继承的规则,自动把构造器的调用写好
//这里也体现: 继承设计的基本思想,父类的构造器完成父类属性初始化
//子类的构造器完成子类属性初始化
public PC(String cpu, int memory, int disk, String brand) {
super(cpu, memory, disk);
this.brand = brand;
}
public String getBrand() {
return brand;
}
public void setBrand(String brand) {
this.brand = brand;
}
public void printInfo() {
System.out.println("PC信息=");
// System.out.println(getCpu() + getMemory() + getDisk());
//调用父类的getDetails方法,得到相关属性信息..
System.out.println(getDetails() + " brand=" + brand);
}
}
package com.hspedu.extend_.exercise;
public class ExtendsExercise03 {
public static void main(String[] args) {
PC pc = new PC("intel", 16, 500, "IBM");
pc.printInfo();
}
}
/*
编写Computer类,包含CPU、内存、硬盘等属性,getDetails方法用于返回Computer的详细信息
编写PC子类,继承Computer类,添加特有属性【品牌brand】
编写NotePad子类,继承Computer类,添加特有属性【color】//同学们自己写。
编写Test类,在main方法中创建PC和NotePad对象,分别给对象中特有的属性赋值,
以及从Computer类继承的属性赋值,并使用方法并打印输出信息
*/
==> 视频链接
super 代表父类的引用,用于访问父类的属性、方法、构造器
(1)访问父类的属性,但不能访问父类的private属性
super.属性名;
(2)访问父类的方法,不能访问父类的private方法
super.方法名(参数列表);
(3)访问父类的构造器
super(参数列表);//只能放在构造器的第一句,只能出现一句!
package com.hspedu.super_;
public class Base { //父类是Object
public int n1 = 999;
public int age = 111;
public void cal() {
System.out.println("Base类的cal() 方法...");
}
public void eat() {
System.out.println("Base类的eat().....");
}
}
package com.hspedu.super_;
public class A extends Base{
//4个属性
//public int n1 = 100;
protected int n2 = 200;
int n3 = 300;
private int n4 = 400;
public A() {}
public A(String name) {}
public A(String name, int age) {}
// public void cal() {
// System.out.println("A类的cal() 方法...");
// }
public void test100() {
}
protected void test200() {
}
void test300() {
}
private void test400() {
}
}
package com.hspedu.super_;
public class B extends A {
public int n1 = 888;
//编写测试方法
public void test() {
//super的访问不限于直接父类,如果爷爷类和本类中有同名的成员,也可以使用super去访问爷爷类的成员;
// 如果多个基类(上级类)中都有同名的成员,使用super访问遵循就近原则。A->B->C
System.out.println("super.n1=" + super.n1);
super.cal();
}
//访问父类的属性 , 但不能访问父类的private属性 [案例]super.属性名
public void hi() {
System.out.println(super.n1 + " " + super.n2 + " " + super.n3 );
}
public void cal() {
System.out.println("B类的cal() 方法...");
}
public void sum() {
System.out.println("B类的sum()");
//希望调用父类-A 的cal方法
//这时,因为子类B没有cal方法,因此我可以使用下面三种方式
//找cal方法时(cal() 和 this.cal()),顺序是:
// (1)先找本类,如果有,则调用
// (2)如果没有,则找父类(如果有,并可以调用,则调用)
// (3)如果父类没有,则继续找父类的父类,整个规则,就是一样的,直到 Object类
// 提示:如果查找方法的过程中,找到了,但是不能访问, 则报错, cannot access
// 如果查找方法的过程中,没有找到,则提示方法不存在
//cal();
this.cal(); //等价 cal()
//找cal方法(super.call()) 的顺序是直接查找父类,其他的规则一样
//super.cal();
//演示访问属性的规则
//n1 和 this.n1 查找的规则是
//(1) 先找本类,如果有,则调用
//(2) 如果没有,则找父类(如果有,并可以调用,则调用)
//(3) 如果父类没有,则继续找父类的父类,整个规则,就是一样的,直到 Object类
// 提示:如果查找属性的过程中,找到了,但是不能访问, 则报错, cannot access
// 如果查找属性的过程中,没有找到,则提示属性不存在
System.out.println(n1);
System.out.println(this.n1);
//找n1 (super.n1) 的顺序是直接查找父类属性,其他的规则一样
System.out.println(super.n1);
}
//访问父类的方法,不能访问父类的private方法 super.方法名(参数列表);
public void ok() {
super.test100();
super.test200();
super.test300();
//super.test400();//不能访问父类private方法
}
//访问父类的构造器(这点前面用过):super(参数列表);只能放在构造器的第一句,只能出现一句!
public B() {
//super();
//super("jack", 10);
super("jack");
}
}
package com.hspedu.super_;
public class Super01 {
public static void main(String[] args) {
B b = new B();//子类对象
//b.sum();
b.test();
}
}
==> 属性和方法的调用细节
简单地说:方法覆盖(重写)就是子类有一个方法,和父类的某个方法和名称、返回类型、参数一样,那么我们就说子类的这个方法覆盖了父类的方法。
package com.hspedu.override_;
public class Animal {
public void cry() {
System.out.println("动物叫唤..");
}
public Object m1() {
return null;
}
public String m2() {
return null;
}
public AAA m3() {
return null;
}
protected void eat() {
}
}
package com.hspedu.override_;
public class Dog extends Animal{
//解读
//1. 因为Dog 是 Animal子类
//2. Dog的 cry方法和 Animal的 cry定义形式一样(名称、返回类型、参数)
//3. 这时我们就说 Dog的cry方法,重写了Animal的cry方法
public void cry() {
System.out.println("小狗汪汪叫..");
}
//细节: 子类方法的返回类型和父类方法返回类型一样,
// 或者是父类返回类型的子类 比如 父类 返回类型是 Object ,
// 子类方法返回类型是String
public String m1() {
return null;
}
//这里Object 不是 String的子类,因此编译错误
// public Object m2() {
// return null;
// }
// public BBB m3() {
// return null;
// }
//细节: 子类方法不能缩小父类方法的访问权限 【演示】
//public > protected > 默认>private
public void eat() {
}
}
class AAA {
}
class BBB extends AAA {
}
package com.hspedu.override_;
public class Override01 {
public static void main(String[] args) {
//演示方法重写的情况
Dog dog = new Dog();
dog.cry();//ctrl+b
}
}
方法重写也叫方法覆盖,需要满足下面的条件:
public > protected > 默认 > private
==> 视频链接
方法或对象具有多种形态。是面向对象的第三大特征,多态是建立在封装和继承基础之上的。
package com.hspedu.poly_;
public class PloyMethod {
public static void main(String[] args) {
//方法重载体现多态
A a = new A();
//这里我们传入不同的参数,就会调用不同sum方法,就体现多态
System.out.println(a.sum(10, 20));
System.out.println(a.sum(10, 20, 30));
//方法重写体现多态
B b = new B();
a.say();
b.say();
}
}
class B { //父类
public void say() {
System.out.println("B say() 方法被调用...");
}
}
class A extends B {//子类
public int sum(int n1, int n2){//和下面sum 构成重载
return n1 + n2;
}
public int sum(int n1, int n2, int n3){
return n1 + n2 + n3;
}
public void say() {
System.out.println("A say() 方法被调用...");
}
}
对象的多态 (核心,困难,重点)
package com.hspedu.poly_.objectpoly_;
public class Animal {
public void cry() {
System.out.println("Animal cry() 动物在叫....");
}
}
package com.hspedu.poly_.objectpoly_;
public class Cat extends Animal {
public void cry() {
System.out.println("Cat cry() 小猫喵喵叫...");
}
}
package com.hspedu.poly_.objectpoly_;
public class Dog extends Animal {
public void cry() {
System.out.println("Dog cry() 小狗汪汪叫...");
}
}
package com.hspedu.poly_.objectpoly_;
public class PolyObject {
public static void main(String[] args) {
//体验对象多态特点
//animal 编译类型就是 Animal , 运行类型 Dog
Animal animal = new Dog();
//因为运行时 , 执行到改行时,animal运行类型是Dog,所以cry就是Dog的cry
animal.cry(); //小狗汪汪叫
//animal 编译类型 Animal,运行类型就是 Cat
animal = new Cat();
animal.cry(); //小猫喵喵叫
}
}
==> 视频链接
父类类型 引用名 = new 子类类型();
子类类型 引用名 = (子类类型) 父类引用
package com.hspedu.poly_.detail_;
public 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,你好");
}
}
package com.hspedu.poly_.detail_;
public class Cat extends Animal {
public void eat(){//方法重写
System.out.println("猫吃鱼");
}
public void catchMouse(){//Cat特有方法
System.out.println("猫抓老鼠");
}
}
package com.hspedu.poly_.detail_;
public class Dog extends Animal {//Dog是Animal的子类
}
package com.hspedu.poly_.detail_;
public class PolyDetail {
public static void main(String[] args) {
//向上转型: 父类的引用指向了子类的对象
//语法:父类类型引用名 = new 子类类型();
Animal animal = new Cat();
Object obj = new Cat();//可以吗? 可以 Object 也是 Cat的父类
//向上转型调用方法的规则如下:
//(1)可以调用父类中的所有成员(需遵守访问权限)
//(2)但是不能调用子类的特有的成员
//(3)因为在编译阶段,能调用哪些成员,是由编译类型来决定的
//animal.catchMouse();错误
//(4)最终运行效果看子类(运行类型)的具体实现, 即调用方法时,按照从子类(运行类型)开始查找方法
//,然后调用,规则我前面我们讲的方法调用规则一致。
animal.eat();//猫吃鱼..
animal.run();//跑
animal.show();//hello,你好
animal.sleep();//睡
//我们希望,可以调用Cat的 catchMouse方法
//多态的向下转型
//(1)语法:子类类型 引用名 =(子类类型)父类引用;
//问一个问题? cat 的编译类型 Cat,运行类型是 Cat
Cat cat = (Cat) animal;
cat.catchMouse();//猫抓老鼠
//(2)要求父类的引用必须指向的是当前目标类型的对象
Dog dog = (Dog) animal; //可以吗?
System.out.println("ok~~");
}
}
属性的值看编译类型
package com.hspedu.poly_.detail_;
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;//属性
}
用于判断对象的运行类型是否为 XX 类型或 XX 类型的子类型
package com.hspedu.poly_.detail_;
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);
System.out.println(str instanceof Object);//true
}
}
class AA {} //父类
class BB extends AA {}//子类
public class PolyExercise01 {
public static void main(String[] args) {
double d = 13.4; //ok
long l = (long)d; //ok
System.out.println(l); //13
int in = 5; //ok
boolean b = (boolean)in; //不对, boolean -> int
Object obj = "Hello"; //可以, 向上转型
String objStr = (String)obj; //可以, 向下转型
System.out.println(objStr); //Hello
Object objPri = new Integer(5); //可以, 向上转型
String str = (String)objPri; //错误 ClassCastException , 指向Integer的父类引用, 转成String
Integer str1 = (Integer)objPri; //可以, 向下转型
}
package com.hspedu.poly_;
public class PolyExercise02 {
public static void main(String[] args) {
Sub s = new Sub();
System.out.println(s.count);//20
s.display();//20
Base b = s;
System.out.println(b == s);//T
System.out.println(b.count);//10
b.display();//20
}
}
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);
}
}
==> 视频链接
java 的动态绑定机制:
package com.hspedu.poly_.dynamic_;
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;
// }
}
数组的定义类型为父类类型,里面保存的实际元素类型为子类类型
应用实例:
package com.hspedu.poly_.polyarr_;
public 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 + "\t" + age;
}
}
package com.hspedu.poly_.polyarr_;
public 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;
}
//重写父类say
@Override
public String say() {
return "学生 " + super.say() + " score=" + score;
}
//特有的方法
public void study() {
System.out.println("学生 " + getName() + " 正在学java...");
}
}
package com.hspedu.poly_.polyarr_;
public class Teacher extends Person {
private double salary;
public Teacher(String name, int age, double salary) {
super(name, age);
this.salary = salary;
}
public double getSalary() {
return salary;
}
public void setSalary(double salary) {
this.salary = salary;
}
//写重写父类的say方法
@Override
public String say() {
return "老师 " + super.say() + " salary=" + salary;
}
//特有方法
public void teach() {
System.out.println("老师 " + getName() + " 正在讲java课程...");
}
}
package com.hspedu.poly_.polyarr_;
public class PloyArray {
public static void main(String[] args) {
//应用实例:现有一个继承结构如下:要求创建1个Person对象、
// 2个Student 对象和2个Teacher对象, 统一放在数组中,并调用每个对象say方法
Person[] persons = new Person[5];
persons[0] = new Person("jack", 20);
persons[1] = new Student("mary", 18, 100);
persons[2] = new Student("smith", 19, 30.1);
persons[3] = new Teacher("scott", 30, 20000);
persons[4] = new Teacher("king", 50, 25000);
//循环遍历多态数组,调用say
for (int i = 0; i < persons.length; i++) {
//提示: person[i] 编译类型是 Person ,运行类型是是根据实际情况有JVM来判断
System.out.println(persons[i].say());//动态绑定机制
//这里大家聪明. 使用 类型判断 + 向下转型.
if(persons[i] instanceof Student) {//判断person[i] 的运行类型是不是Student
Student student = (Student)persons[i];//向下转型
student.study();
//小伙伴也可以使用一条语句 ((Student)persons[i]).study();
} else if(persons[i] instanceof Teacher) {
Teacher teacher = (Teacher)persons[i];
teacher.teach();
} else if(persons[i] instanceof Person){
//System.out.println("你的类型有误, 请自己检查...");
} else {
System.out.println("你的类型有误, 请自己检查...");
}
}
}
}
方法定义的形参类型为父类类型,实参类型允许为子类类型
应用实例:
getAnnual()
方法manage()
方法,普通员工类多了work()
方法,普通员工和经理类要求分别重写 getAnnual()
方法showEmpAnnual(Employee e)
,实现获取任何员工对象的年工资,并在 main方法中调用该方法[ e.getAnnual()
]testWork()
,如果是普通员工,则调用 work方法,如果是经理,则调用 manage方法package com.hspedu.poly_.polyparameter_;
public class Employee {
private String name;
private double salary;
public Employee(String name, double salary) {
this.name = name;
this.salary = salary;
}
//得到年工资的方法
public double getAnnual() {
return 12 * salary;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getSalary() {
return salary;
}
public void setSalary(double salary) {
this.salary = salary;
}
}
package com.hspedu.poly_.polyparameter_;
public class Manager extends Employee{
private double bonus;
public Manager(String name, double salary, double bonus) {
super(name, salary);
this.bonus = bonus;
}
public double getBonus() {
return bonus;
}
public void setBonus(double bonus) {
this.bonus = bonus;
}
public void manage() {
System.out.println("经理 " + getName() + " is managing");
}
//重写获取年薪方法
@Override
public double getAnnual() {
return super.getAnnual() + bonus;
}
}
package com.hspedu.poly_.polyparameter_;
public class Worker extends Employee {
public Worker(String name, double salary) {
super(name, salary);
}
public void work() {
System.out.println("普通员工 " + getName() + " is working");
}
@Override
public double getAnnual() { //因为普通员工没有其它收入,则直接调用父类方法
return super.getAnnual();
}
}
package com.hspedu.poly_.polyparameter_;
public class PloyParameter {
public static void main(String[] args) {
Worker tom = new Worker("tom", 2500);
Manager milan = new Manager("milan", 5000, 200000);
PloyParameter ployParameter = new PloyParameter();
ployParameter.showEmpAnnual(tom);
ployParameter.showEmpAnnual(milan);
ployParameter.testWork(tom);
ployParameter.testWork(milan);
}
//showEmpAnnual(Employee e)
//实现获取任何员工对象的年工资,并在main方法中调用该方法 [e.getAnnual()]
public void showEmpAnnual(Employee e) {
System.out.println(e.getAnnual());//动态绑定机制.
}
//添加一个方法,testWork,如果是普通员工,则调用work方法,如果是经理,则调用manage方法
public void testWork(Employee e) {
if(e instanceof Worker) {
((Worker) e).work();//有向下转型操作
} else if(e instanceof Manager) {
((Manager) e).manage();//有向下转型操作
} else {
System.out.println("不做处理...");
}
}
}
==> 视频链接
int i = 10;
double d = 10.0;
package com.hspedu.object_;
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);//基本数据类型,判断值是否相等
//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("hspedu");
String str2 = new String("hspedu");
System.out.println(str1 == str2);//false
System.out.println(str1.equals(str2));//true
}
}
class B {}
class A extends B {}
应用实例:判断两个 Person 对象的内容是否相等,如果两个 Person 对象的各个属性值都一样,则返回 true,反之 false。
package com.hspedu.object_;
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));//假
}
}
//判断两个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;
}
}
package com.hspedu.object_;
public class EqualsExercise02 {
public static void main(String[] args) {
Person_ p1 = new Person_();
p1.name = "hspedu";
Person_ p2 = new Person_();
p2.name = "hspedu";
System.out.println(p1==p2); //False
System.out.println(p1.name .equals( p2.name));//T
System.out.println(p1.equals(p2));//False
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;
}
//代码如下 EqualsExercise03.java 2min
int it = 65;
float fl = 65.0f;
System.out.println(“65 和 65.0f 是否相等?” + (it == fl));//T
char ch1 = ‘A’; char ch2 = 12;
System.out.println(“65 和‘A’是否相等?” + (it == ch1));//T
System.out.println(“12 和 ch2 是否相等?” + (12 == ch2));//T
String str1 = new String("hello");
String str2 = new String("hello");
System.out.println("str1 和 str2 是否相等?"+ (str1 == str2)); //F
System.out.println(“str1 是否 equals str2?”+(str1.equals(str2)));//T
System.out.println(“hello” == new java.sql.Date()); //编译错误
package com.hspedu.object_;
public class HashCode_ {
public static void main(String[] args) {
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 {}
System.out.println(monster);
就会默认调用 monster.toString()
package com.hspedu.object_;
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..");
}
}
System.gc()
主动触发垃圾回收机制==> 视频链接
==> 视频链接
定义一个Person类 {name, age, job}
,初始化Person 对象数组,有3个person对象,并按照 age 从 大到 小进行排序,提示,使用冒泡排序
package com.hspedu.homework;
public class Homework01 {
public static void main(String[] args) {
//初始化Person 对象数组,有3个person对象
Person[] persons = new Person[3];
persons[0] = new Person("mary",30, "PHP工程师");
persons[1] = new Person("tom",50, "大数据工程师");
persons[2] = new Person("smith",10, "JavaEE工程师");
//输出当前对象数组
for (int i = 0; i < persons.length; i++) {
System.out.println(persons[i]);//默认对象的.toString()
}
//使用冒泡排序
Person tmp = null;//临时变量,用于交换
for(int i = 0; i < persons.length -1 ;i++) {//外层循环
for(int j = 0; j < persons.length -1 - i; j++) {//内层循环
//并按照 age 从 大到 小进行排序, 如果前面的人的age < 后面人的年龄,就交换
//要求按照名字的长度从小到大 if(persons[i].getName().length() > persons[i+1].getName().length())
if(persons[j].getAge() > persons[j+1].getAge()) {
tmp = persons[j];
persons[j] = persons[j+1];
persons[j+1]= tmp;
}
}
}
System.out.println("排序后的效果");
for (int i = 0; i < persons.length; i++) {
System.out.println(persons[i]);//默认对象的.toString()
}
}
/*
定义一个Person类 {name, age, job}, 初始化Person 对象数组,有3个person对象,
并按照 age 从 大到 小进行排序, 提示,使用冒泡排序
*/
}
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 void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getJob() {
return job;
}
public void setJob(String job) {
this.job = job;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
", job='" + job + '\'' +
'}';
}
}
package com.hspedu.homework;
/*
(1) 要求有属性“姓名name”,“年龄age”,“职称post”,“基本工资salary”
(2) 编写业务方法, introduce(),实现输出一个教师的信息。
*/
public class Teacher {
private String name;
private int age;
private String post;
private double salary;
//这里我们在增加一个工资级别
private double grade;
public Teacher(String name, int age, String post, double salary, double grade) {
this.name = name;
this.age = age;
this.post = post;
this.salary = salary;
this.grade = grade;
}
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 getPost() {
return post;
}
public void setPost(String post) {
this.post = post;
}
public double getSalary() {
return salary;
}
public void setSalary(double salary) {
this.salary = salary;
}
public double getGrade() {
return grade;
}
public void setGrade(double grade) {
this.grade = grade;
}
public void introduce() {
System.out.println("name: " + name + " age: " + age
+ " post: " + post + " salary:" + salary + " grade:" + grade);
}
}
package com.hspedu.homework;
//子类
public class Professor extends Teacher {
//特有属性...
public Professor(String name, int age, String post, double salary, double grade) {
super(name, age, post, salary, grade);
}
@Override
public void introduce() {
System.out.println(" 这是教授的信息 ");
super.introduce();
}
}
package com.hspedu.homework;
public class Homework03 {
public static void main(String[] args) {
Professor professor = new Professor("贾宝玉", 30, "高级职称", 30000, 1.3);
professor.introduce();
}
}
package com.hspedu.homework;
import java.sql.SQLOutput;
public class Employee {
//属性
//员工属性:姓名,单日工资,工作天数
private String name;
private double daySal;
private int workDays;
//分析出还有一个属性等级
private double grade;
//方法[构造器,getter 和 setter]
//打印工资方法
//方法 void printSal() {}
public void printSal() {
System.out.println(name + " 工资=" + daySal * workDays * grade);
}
public Employee(String name, double daySal, int workDays, double grade) {
this.name = name;
this.daySal = daySal;
this.workDays = workDays;
this.grade = grade;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getDaySal() {
return daySal;
}
public void setDaySal(double daySal) {
this.daySal = daySal;
}
public int getWorkDays() {
return workDays;
}
public void setWorkDays(int workDays) {
this.workDays = workDays;
}
public double getGrade() {
return grade;
}
public void setGrade(double grade) {
this.grade = grade;
}
}
package com.hspedu.homework;
public class Manager extends Employee {
//特有属性
private double bonus;
//创建Manager对象时,奖金是多少并不是确定的,因为老师在构造器中,不给bonus
//,可以通过setBonus
public Manager(String name, double daySal, int workDays, double grade) {
super(name, daySal, workDays, grade);
}
//方法:重写父类的 printSal
@Override
public void printSal() {
//因为经理的工资计算方式和Employee不一样,所以我们重写
System.out.println("经理 " + getName() + " 工资是="
+ (bonus + getDaySal() * getWorkDays() * getGrade()));
}
public double getBonus() {
return bonus;
}
public void setBonus(double bonus) {
this.bonus = bonus;
}
}
package com.hspedu.homework;
public class Worker extends Employee{
//分析普通员工没有特有的属性
public Worker(String name, double daySal, int workDays, double grade) {
super(name, daySal, workDays, grade);
}
//重写printSal
//因为普通员工和Employee输出工资情况一下,所以直接调用父类的printSal()
@Override
public void printSal() {
System.out.print("普通员工 ");//自己的输出信息
super.printSal();//调用父类的方法,复用代码
}
}
package com.hspedu.homework;
public class Homework04 {
public static void main(String[] args) {
Manager manage = new Manager("刘备", 100, 20, 1.2);
//设置奖金
manage.setBonus(3000);
//打印经理的工资情况
manage.printSal();
Worker worker = new Worker("关羽",50, 10, 1.0);
worker.printSal();
}
}
package com.hspedu.homework.homework5;
public class Employee { //父类
//属性
//分析有一个带薪的月份 13 , 15, 12
private String name;
private double sal;
private int salMonth = 12;
//方法
//打印全年工资
public void printSal() {
System.out.println(name + " 年工资是: " + (sal * salMonth));
}
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 double getSal() {
return sal;
}
public void setSal(double sal) {
this.sal = sal;
}
public int getSalMonth() {
return salMonth;
}
public void setSalMonth(int salMonth) {
this.salMonth = salMonth;
}
}
package com.hspedu.homework.homework5;
public class Worker extends Employee{ //子类
//属性
//工人,农民,服务生只有基本工资 sal
public Worker(String name, double sal) {
super(name, sal);
}
//方法
@Override
public void printSal() {
System.out.print("工人 ");
super.printSal();//使用父类的printSal()
}
}
package com.hspedu.homework.homework5;
public class Peasant extends Employee {//子类
//属性
//农民,服务生只有基本工资 sal
//方法
public Peasant(String name, double sal) {
super(name, sal);
}
//年工资
@Override
public void printSal() {
System.out.print("农民 ");
super.printSal();
}
}
package com.hspedu.homework.homework5;
public class Teacher extends Employee{//子类
//特有属性
private int classDays; //一年上课次数
private double classSal; //课时费
public Teacher(String name, double sal) {
super(name, sal);
}
//方法-重写printSal
@Override
public void printSal() { //老师不能使用super.printSal()
System.out.print("老师 ");
System.out.println(getName() + " 年工资是: "
+ (getSal() * getSalMonth() + classDays * classSal ));
}
public int getClassDays() {
return classDays;
}
public void setClassDays(int classDays) {
this.classDays = classDays;
}
public double getClassSal() {
return classSal;
}
public void setClassSal(double classSal) {
this.classSal = classSal;
}
}
package com.hspedu.homework.homework5;
public class Scientist extends Employee{ //子类
//特有属性
//年终奖 bonus
private double bonus;
//方法
public Scientist(String name, double sal) {
super(name, sal);
}
//重写年工资打印
@Override
public void printSal() {
System.out.print("科学家 ");
System.out.println(getName() + " 年工资是: " + (getSal() * getSalMonth() + bonus));
}
public double getBonus() {
return bonus;
}
public void setBonus(double bonus) {
this.bonus = bonus;
}
}
package com.hspedu.homework.homework5;
public class Homework05 {
public static void main(String[] args) {
Worker jack = new Worker("jack", 10000);
jack.setSalMonth(15);//灵活额修改带薪月份
jack.printSal();
Peasant smith = new Peasant("smith", 20000);
smith.printSal();
//老师测试
Teacher teacher = new Teacher("顺平", 2000);
//老师有课时费
teacher.setClassDays(360);
teacher.setClassSal(1000);
teacher.printSal();
//科学家
Scientist scientist = new Scientist("钟南山", 20000);
scientist.setBonus(2000000);
scientist.printSal();
}
}
package com.hspedu.homework;
public class BankAccount {//父类
private double balance ;//余额
public BankAccount(double initialBalance) {
this.balance = initialBalance;
}
//存款
public void deposit(double amount) {
balance += amount;
}
//取款
public void withdraw(double amount) {
balance -= amount;
}
public double getBalance() {
return balance;
}
public void setBalance(double balance) {
this.balance = balance;
}
}
package com.hspedu.homework;
/*
在上面类的基础上扩展 新类CheckingAccount对每次存款和取款都收取1美元的手续费
*/
public class CheckingAccount extends BankAccount{//新的账号
//属性
public CheckingAccount(double initialBalance) {
super(initialBalance);
}
@Override
public void deposit(double amount) {//存款
super.deposit(amount - 1);//巧妙的使用了父类的 deposit
//1 块钱转入银行的账号
}
@Override
public void withdraw(double amount) {//取款
super.withdraw(amount + 1);
//1 块钱转入银行的账号
}
}
package com.hspedu.homework;
/*
扩展前一个练习的BankAccount类,
新类SavingsAccount每个月都有利息产生(earnMonthlyInterest方法被调用),
并且有每月三次免手续费的存款或取款。在earnMonthlyInterest方法中重置交易计数
*/
public class SavingsAccount extends BankAccount {
//分析
//新增加属性
private int count = 3;
private double rate = 0.01;//利率
public void earnMonthlyInterest() {//每个月初,我们统计上个月的利息,同时将count=3
count = 3;//
super.deposit(getBalance() * rate);
}
@Override
public void deposit(double amount) {
//判断是否还可以免手续费
if(count > 0) {
super.deposit(amount);
} else {
super.deposit(amount - 1);//1 块转入银行
}
count--;//减去一次
}
@Override
public void withdraw(double amount) {//取款
//判断是否还可以免手续费
if(count > 0) {
super.withdraw(amount);
} else {
super.withdraw(amount + 1);//1 块转入银行
}
count--;
}
public SavingsAccount(double initialBalance) {
super(initialBalance);
}
public int getCount() {
return count;
}
public void setCount(int count) {
this.count = count;
}
public double getRate() {
return rate;
}
public void setRate(double rate) {
this.rate = rate;
}
}
package com.hspedu.homework;
public class Homework08 {
public static void main(String[] args) {
// CheckingAccount checkingAccount = new CheckingAccount(1000);
// checkingAccount.deposit(10);// 1010 - 1 = 1009
// checkingAccount.withdraw(9);//1009 - 9 = 1000 -1= 999
// System.out.println(checkingAccount.getBalance());
//测试SavingsAccount
SavingsAccount savingsAccount = new SavingsAccount(1000);
savingsAccount.deposit(100);
savingsAccount.deposit(100);
savingsAccount.deposit(100);
System.out.println(savingsAccount.getBalance());//1300
savingsAccount.deposit(100);
System.out.println(savingsAccount.getBalance());//1400-1=1399
//月初,定时器自动调用一下 earnMonthlyInterest
savingsAccount.earnMonthlyInterest();//统计利息
System.out.println(savingsAccount.getBalance());//1399 + 13.99 =1412.99
savingsAccount.withdraw(100);//免手续
System.out.println(savingsAccount.getBalance());//1412.99 -100 =1312.99
savingsAccount.withdraw(100);//免手续
savingsAccount.withdraw(100);//免手续
System.out.println(savingsAccount.getBalance());//1412.99 -200 =1112.99
savingsAccount.deposit(100);//扣手续费
System.out.println(savingsAccount.getBalance());//1112.99 + 100 = 1212.99 - 1 = 1211.99
}
}
package com.hspedu.homework;
public class Point {
private double x;
private double y;
public Point(double x, double y) {
this.x = x;
this.y = y;
}
}
package com.hspedu.homework;
public class LabeledPoint extends Point {
//特有属性
private String label;
public LabeledPoint(String label, double x, double y) {
super(x, y);
this.label = label;
}
//方法
}
package com.hspedu.homework;
public class Homework09 {
public static void main(String[] args) {
new LabeledPoint("Black",1929,230.07);
}
}
package com.hspedu.homework;
public class Doctor {
//属性
//{name, age, job, gender, sal}
private String name;
private int age;
private String job;
private char gender;
private double sal;
//5个参数的构造器
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;
}
//方法
//相应的getter()和setter()方法
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 getJob() {
return job;
}
public void setJob(String job) {
this.job = job;
}
public char getGender() {
return gender;
}
public void setGender(char gender) {
this.gender = gender;
}
public double getSal() {
return sal;
}
public void setSal(double sal) {
this.sal = sal;
}
//重写父类(Object)的equals()方法:public boolean equals(Object obj),并判断测试类中创建的两个对象是否相等。相等就是判断属性是否相同
public boolean equals(Object obj) {
//判断两个比较对象是否相同
if (this == obj) {
return true;
}
//判断obj 是否是 Doctor类型或其子类
//过关斩将 校验方式
if (!(obj instanceof Doctor)) { //不是的话
return false;
}
//向下转型, 因为obj的运行类型是Doctor或者其子类型
Doctor doctor = (Doctor)obj;
return this.name.equals(doctor.name) && this.age == doctor.age &&
this.gender == doctor.gender && this.job.equals(doctor.job) && this.sal == doctor.sal;
}
}
package com.hspedu.homework;
public class Homework10 {
public static void main(String[] args) {
//测试
Doctor doctor1 = new Doctor("jack", 20, "牙科医生", '男', 20000);
Doctor doctor2 = new Doctor("jack", 21, "牙科医生", '男', 20000);
System.out.println(doctor1.equals(doctor2));//T
}
}
package com.hspedu.homework.homework13;
/*
抽取一个父类Person类,将共同属性和方法放到Person类
*/
public class Person {//父类
private String name;
private char gender;
private int age;
//方法
public Person(String name, char gender, int age) {
this.name = name;
this.gender = gender;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public char getGender() {
return gender;
}
public void setGender(char gender) {
this.gender = gender;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
//编写一个play 方法, 把共有的输出内容写到父类
public String play() {
return name + "爱玩";
}
//返回一个基本信息
/*
姓名:张飞
年龄:30
性别:男
*/
public String basicInfo() {
return "姓名: " + name + "\n年龄: " + age + "\n性别: " + gender;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", gender=" + gender +
", age=" + age +
'}';
}
}
package com.hspedu.homework.homework13;
/*
Student类有名称(name),性别(sex),年龄(age),学号(stu_id),
做合理封装,通过构造器在创建对象时将4个属性赋值。
学生需要有学习的方法(study),在方法里写生“我承诺,我会好好学习。”
*/
public class Student extends Person{ //
//属性
private String stu_id;
//方法
public Student(String name, char gender, int age, String stu_id) {
super(name, gender, age);
this.stu_id = stu_id;
}
public String getStu_id() {
return stu_id;
}
public void setStu_id(String stu_id) {
this.stu_id = stu_id;
}
//我承诺,我会好好学习
public void study() {
System.out.println(getName() + "承诺,我会好好学习 老韩讲的 java");
}
/**
* 学生爱玩足球
* @return
*/
@Override
public String play() {
return super.play() + "足球";
}
//编写一个输出信息的方法,这样体现封装
public void printInfo() {
System.out.println("学生的信息:");
System.out.println(super.basicInfo());
System.out.println("学号: " + stu_id);
study();//组合, 变化万千
System.out.println(play());
}
@Override
public String toString() {
return "Student{" +
"stu_id='" + stu_id + '\'' +
'}' + super.toString();
}
}
package com.hspedu.homework.homework13;
/*
写一个Teacher类,Teacher类有名称(name),性别(sex),年龄(age),工龄(work_age),
做合理封装,通过构造器在创建对象时将4个属性赋值
*/
public class Teacher extends Person {
//属性
private int work_age;
//方法
public Teacher(String name, char gender, int age, int work_age) {
super(name, gender, age);
this.work_age = work_age;
}
public int getWork_age() {
return work_age;
}
public void setWork_age(int work_age) {
this.work_age = work_age;
}
//教师需要有教学的方法(teach),在方法里写上“我承诺,我会认真教学。
public void teach() {
System.out.println(getName() + "承诺,我会认真教学 java...");
}
/**
* 老师爱玩象棋
*/
@Override
public String play() {
return super.play() + "象棋";
}
//输出信息方法
public void printInfo() {
System.out.println("老师的信息:");
System.out.println(super.basicInfo());
System.out.println("工龄: " + work_age);
teach();
System.out.println(play());
}
@Override
public String toString() {
return "Teacher{" +
"work_age=" + work_age +
'}' + super.toString();
}
}
package com.hspedu.homework.homework13;
public class Homework13 {
public static void main(String[] args) {
//测试老师
Teacher teacher = new Teacher("张飞", '男', 30, 5);
teacher.printInfo();
//测试
Student student = new Student("小明", '男', 15, "00023102");
System.out.println("-----------------------------------");
student.printInfo();//封装
//定义多态数组,里面保存2个学生和2个教师,要求按年龄从高到低排序
Person[] persons = new Person[4];
persons[0] = new Student("jack", '男', 10, "0001");
persons[1] = new Student("mary", '女', 20, "0002");
persons[2] = new Teacher("smith", '男', 36, 5);
persons[3] = new Teacher("scott", '男', 26, 1);
//创建对象
Homework13 homework13 = new Homework13();
homework13.bubbleSort(persons);
//输出排序后的数组
System.out.println("---排序后的数组-----");
for(int i = 0; i < persons.length; i++) {
System.out.println(persons[i]);
}
//遍历数组,调用test方法
System.out.println("=======================");
for (int i = 0; i < persons.length; i++) {//遍历多态数组
homework13.test(persons[i]);
}
}
//定义方法,形参为Person类型,功能:调用学生的study或教师的teach方法
//分析这里会使用到向下转型和类型判断
public void test(Person p) {
if(p instanceof Student) {//p 的运行类型如果是Student
((Student) p).study();
} else if(p instanceof Teacher) {
((Teacher) p).teach();
} else {
System.out.println("do nothing...");
}
}
//方法,完成年龄从高到底排序
public void bubbleSort(Person[] persons) {
Person temp = 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()) {
temp = persons[j];
persons[j] = persons[j + 1];
persons[j + 1] = temp;
}
}
}
}
}