面向对象编程中
面向对象特征之二:继承性
1 继承性的好处
- 减少了代码的冗余,提高了代码的复用性
- 便于功能的扩展
- 为之后多态性的使用,提供了前提
2 继承性的格式:class A extends B {}
- A : 子类,派生类,subclass
- B:父类,超类,基类,superclass
- 体现:一旦子类A继承父类B以后,子类A就获取了父类B中声明的所有的属性和方法
- 特别的,父类中声明为private的属性或方法,子类继承父类以后,仍然认为获取了父类中私有的结构,只是因为封装性的影响,使得子类不能直接调用父类的结构而已。
- 子类继承父类以后,还可以声明自己特有的属性和方法,实现功能的扩展。所以子类更加强大
- extends:延展,扩展
3 java中关于继承性的一些规定
- 一个类可以被多个子类继承
- java中类的单继承性:一个类只能有一个父类
- 子父类是相对的概念
- 子类直接继承的父类称为直接父类,间接继承的父类叫做间接父类
- 子类继承父类以后,就获得了直接父类以及所有间接父类中声明的属性和方法
4 object类
- 如果我们没有显示的声明一个类的父类的话,则此类继承于java.lang.Object类
- 所有的java类(除java.lang.Object类之外)都直接或间接的继承于 java.lang.Object类
- 意味着 所有的java类具有java.lang.Object类声明的功能
练习1 定义一个学生类Student,它继承自Person类
package com.atguigu.exer4;
public class Person{
String name;
char sex;
int age;
public Person() {
}
public Person(String name,char sex,int age) {
this.name = name;
this.sex = sex;
this.age = age;
}
public String toString() {
return "姓名:" + name + ",性别:" + sex + ",年龄:" + age;
}
}
package com.atguigu.exer4;
public class Student extends Person{
long number;
int math;
int English;
int computer;
public Student(String n,char s,int a,long k,int m,int e,int c) {
this.name = n;
this.sex = s;
this.age = a;
this.number = k;
this.math = m;
this.English = e;
this.computer = c;
}
public double aver() {
return (math + English + computer) / 3.0;
}
public int max() {
int temp = (math > English)?math:English;
return (temp > computer)?temp:computer;
}
public int min() {
int temp = (math < English)?math:English;
return (temp < computer)?temp:computer;
}
public String toString1() {
return "个人信息" ;
}
}
练习2 按照下列描述给出程序
(1)定义一个ManKind类,包括
成员变量int sex和int salary;
方法void manOrWoman():根据sex的值显示“man”(sex==1)或者“woman”(sex==0);
方法void employeed():根据salary的值显示“no job”(salary==0)或者“ job”(salary!=0)。
(2)定义类Kids继承ManKind,并包括
成员变量int yearsOld;
方法printAge()打印yearsOld的值。
(3)定义类KidsTest,在类的main方法中实例化Kids的对象someKid,用该对象访问
其父类的成员变量及方法。
package com.atguigu.exer4;
public class ManKind {
int sex;
int salary;
public ManKind() {
}
public void manOrWoman() {
if(sex == 1) {
System.out.println("男");
}else if(sex == 0) {
System.out.println("女");
}
}
public void employeed() {
if(salary == 0) {
System.out.println("no job");
}else {
System.out.println("job");
}
}
}
package com.atguigu.exer4;
public class Kids extends ManKind{
int yearsOld;
public Kids() {
}
public void printAge() {
System.out.println("yearsOld:" + yearsOld);
}
}
package com.atguigu.exer4;
public class KidsTest {
public static void main(String[] args) {
Kids someKid = new Kids();
someKid.sex = 1;
someKid.salary = 50;
someKid.yearsOld = 20;
someKid.manOrWoman();
someKid.employeed();
someKid.printAge();
}
}
练习3 根据下图实现类
在CylinderTest类中创建Cylinder类的对象,设置圆柱的底面半径和高,并输出圆柱的体积。
package com.atguigu.exer4;
public class Circle {
private double radius;
public Circle() {
this.radius = 1;
}
public void setRadius(double radius) {
this.radius = radius;
}
public double getRadius() {
return this.radius;
}
public double findArea() {
return Math.PI*radius*radius;
}
}
package com.atguigu.exer4;
public class Cylinder extends Circle {
private double length;
public Cylinder() {
this.length = 1;
}
public void setLength(double length) {
this.length = length;
}
public double getLength() {
return this.length;
}
public double findVolume() {
return Math.PI * getRadius() * getRadius() * length;
}
}
package com.atguigu.exer4;
public class CylinderTest {
public static void main(String[] args) {
Cylinder cyc = new Cylinder();
cyc.setRadius(4.2);
cyc.setLength(4);
System.out.println("圆柱的体积为:" + cyc.findVolume());
}
}
方法的重写(override/overwrite)
1 重写:子类继承父类以后,可以对父类中同名同参数的方法,进行覆盖操作
2 应用:重写以后,当创建子类对象以后,通过子类对象调用父类中同名同参数的方法时,实际执行的是子类重写父类的方法
3 重写的规定:
-
方法的声明:权限修饰符 返回值类型 方法名(形参列表) throws 异常类型 { 方法体; }
-
约定俗成:子类中叫做重写方法,父类中的叫做被重写的方法
-
子类重写方法的 方法名和形参列表 与父类中被重写方法 相同
-
子类重写方法的 权限修饰符 大于等于 父类中被重写方法
特殊情况:子类不能重写父类中声明为private权限的方法 -
返回值类型
父类被重写方法的返回值是void类型,则子类重写方法的返回值类型只能是void
父类被重写方法的返回值是 A 类型,则子类重写方法的返回值类型是 A类或者 A类的子类
父类被重写方法的返回值是 基本数据类型,则子类重写方法的返回值类型必须是相同的基本数据类型 -
子类重写方法的 抛出的异常类型 小于等于 父类被重写方法 (具体放到异常处理去讲)
-
子类和父类中同名同参数的方法要么声明为非static类型(考虑重写),要么都声明为static类型(不可以重写)
面试题 区分方法的重载与重写
方法重写练习题
1 如果现在父类的一个方法定义成private访问权限,在子类中将此方法声明为default访问权限,那么这样还叫重写吗?
不叫,子类不能重写父类中声明为private权限的方法:
2 修改练习1.2中定义的类Kids,在Kids中重新定义employeed()方法,覆盖父类ManKind中定义的employeed()方法,输出“Kids should study and no job.”
package com.atguigu.exer4;
public class Kids extends ManKind{
int yearsOld;
public Kids() {
}
public void printAge() {
System.out.println("yearsOld:" + yearsOld);
}
public void employeed() {
System.out.println("Kids should study and no job");
}
}
关键字:super
super关键字的使用
super可以理解为:父类的
super可以用来调用:属性 方法 构造器
super的使用:属性或方法
- 我们可以在子类的方法或构造器中。通过使用"super.属性"或"super.方法"的方式,显式的调用父类中声明的属性或方法。但是,通常情况下,我们习惯省略"super"
- 特殊情况:当子类和父类中定义了同名的属性时,我们想要在子类中调用父类中声明的属性,则必须是显式使用 “super.属性” 的方式,表明调用的是父类中声明的属性
- 特殊情况:当子类重写父类中的方法以后,我们想要在子类的方法中调用父类被重写的方法时,则必须显示使用 “super.方法” 的方式,表明调用的是父类中声明的方法
super调用构造器
- 可以在子类的构造器中显式的使用 “super(形参列表)” 的方式,调用父类中声明的指定构造器
- “super(形参列表)” 的使用,必须声明在子类构造器的首行
- 在类的构造器中,针对于 “this(形参列表)” 或 “super(形参列表)” 只能二选一 ,不能同时出现
- 在构造器的首行,没有显式的声明 “this(形参列表)” 或 “super(形参列表)” 则默认调用的是父类中空参的构造器:super()
- 在类的多个构造器中,至少有一个类的构造器使用了 “super(形参列表)” ,调用父类中的构造器
package com.atguigu.exer4;
public class Person {
String name;
int age;
int id = 1001;
public Person() {
}
public Person(String name) {
this.name = name;
}
public Person(String name, int age) {
this(name);
this.age = age;
}
public void eat() {
System.out.println("吃饭");
}
public void walk() {
System.out.println("走路");
}
}
package com.atguigu.exer4;
public class Student extends Person{
String major;
int id = 1002;
public Student() {
}
public Student(String major) {
this.major = major;
}
public Student(String name,int age,String major) {
super(name,age);
this.major = major;
}
public void study() {
System.out.println("学生应该努力学习!");
}
//对父类中的eat方法进行了重写
public void eat() {
System.out.println("学生多吃有营养的食物");
}
public void show() {
System.out.println("name = " + this.name + ",age = " + super.age);
System.out.println("id = " + this.id);
System.out.println("id = " + super.id);
}
}
package com.atguigu.exer4;
public class superTest {
public static void main(String[] args) {
Student s = new Student();
s.show();
Student s1 = new Student("Tom",55,"计算机");
s1.show();
}
}
课后实验题: 实验-继承&super.doc
package com.atguigu.java1;
public class Account {
private int id;
private double balance;
private double annualInterestRate;
public Account() {
}
public Account (int id, double balance, double annualInterestRate ) {
this.id = id;
this.balance = balance;
this.annualInterestRate = annualInterestRate;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public double getBalance() {
return balance;
}
public void setBalance(double balance) {
this.balance = balance;
}
public double getAnnualInterestRate() {
return annualInterestRate;
}
public void setAnnualInterestRate(double annualInterestRate) {
this.annualInterestRate = annualInterestRate;
}
/**
* @Description : 计算月利率
* @ahthor : 099
* @data 2021年1月17日下午4:15:41
* @return 月利率
*/
public double getMonthlyInterest() {
return annualInterestRate / 12;
}
/**
* @Description : 取钱
* @ahthor : 099
* @data 2021年1月17日下午4:16:11
* @param amount 取钱金额
*/
public void withdraw (double amount) {
if(balance < amount) {
System.out.println("余额不足!");
}else {
balance -= amount;
}
}
/**
* @Description : 存钱
* @ahthor : 099
* @data 2021年1月17日下午4:16:33
* @param amount 存钱金额
*/
public void deposit (double amount) {
if(amount > 0) {
balance += amount;
return;
}
}
}
package com.atguigu.java1;
public class CheckAccount extends Account{
double overdraft;
public CheckAccount() {
}
public CheckAccount(int id, double balance, double annualInterestRate,double overdraft) {
super(id,balance,annualInterestRate);
this.overdraft = overdraft;
}
public void withdraw (double amount) {
if(amount <= getBalance()) {
setBalance(getBalance() - amount);
}else {
double value = amount - getBalance();
if(overdraft > value) {
setBalance(0);
overdraft -= value;
}else {
System.out.println("超过可透支额的限额");
}
}
}
}
package com.atguigu.java1;
public class CheckAccountTest {
public static void main(String[] args) {
CheckAccount chacc = new CheckAccount(1122,20000,0.045,5000);
chacc.withdraw(5000);
System.out.println("你的账户余额:" + chacc.getBalance());
System.out.println("你的可透支金额:" + chacc.overdraft);
System.out.println();
chacc.withdraw(18000);
System.out.println("你的账户余额:" + chacc.getBalance());
System.out.println("你的可透支金额:" + chacc.overdraft);
System.out.println();
chacc.withdraw(3000);
System.out.println("你的账户余额:" + chacc.getBalance());
System.out.println("你的可透支金额:" + chacc.overdraft);
}
}
子类对象实例化的全过程
从结果上来看,(继承性)
- 子类继承父类以后,就获取了父类中声明的属性或方法
- 创建子类的对象,在堆空间中,就会加载所有父类中声明的属性
从过程上来看,
- 当我们通过子类的构造器创建子类对象时,我们一定会直接或者间接的调用其父类的构造器,进而调用父类的父类的构造器,,,直到调用了java.lang.Object类中空参的构造器为止,正因为加载过所有的父类结构,所以才可以看到内存中有父类中的结构,子类对象才可以考虑调用
需明确:虽然创建子类对象时,调用了父类的构造器,但是自始至终就创建过一个对象,即为 new 的子类对象
面向对象特征之三:多态性
1 理解多态性:可以理解为一个事物的多种形态。
2 何为多态性:
- 对象的多态性:父类的引用指向子类的对象(或者子类的对象赋给父类使用)
3 多态的使用:虚拟方法调用(当调用子父类同名同参数的方法时,实际执行的是子类重写父类的方法)
- 有了对象的多态性以后,我们在编译期,只能调用父类声明的方法,但在执行期,我们实际执行的是子类重写父类的方法
- 总结:编译看左边,运行看右边
4 多态性的使用前提:
- 存在类的继承关系
- 存在方法的重写
5 对象的多态性,只适用于方法,不适用于属性。
- 属性(编译和运行都看左边)
多态的举例1
package com.atguigu.java1;
public class AnimalTest {
public static void main(String[] args) {
AnimalTest test = new AnimalTest();
test.func(new Dog());
System.out.println();
test.func(new Cat());
}
public void func(Animal animal) {
animal.eat();
animal.shout();
}
}
class Animal{
public void eat() {
System.out.println("动物:进食");
}
public void shout() {
System.out.println("动物:叫");
}
}
class Dog extends Animal{
public void eat() {
System.out.println("狗吃骨头");
}
public void shout() {
System.out.println("汪!汪!汪");
}
}
class Cat extends Animal{
public void eat() {
System.out.println("猫吃鱼");
}
public void shout() {
System.out.println("喵!喵!喵");
}
}
虚拟方法调用(Virtual Method Invocation)
- 正常的方法调用
Person e = new Person();
e.getInfo();
Student e = new Student();
e.getInfo();
- 虚拟方法调用(多态情况下)
子类中定义了与父类同名同参数的方法,在多态情况下,将此时父类的方法称为虚拟方法,父类根据赋给它的不同子类对象,动态调用属于子类的该方法。这样的方法调用在编译期是无法确定的。注意:多态是运行时行为
Person e = new Student();
e.getInfo(); //调用Student类的getInfo()方法
- 编译时类型和运行时类型
编译时e为Person类型,而方法的调用是在运行时确定的,所以调用的是Student类的getInfo()方法。——动态绑定
关键字:instanceof
前景提要
- 多态的使用:创建的父类对象不能调用子类特有的方法和属性
- 对上句话的解释:有了对象的多态性以后,内存中实际上是加载了子类特有的属性和方法,但是由于变量声明为父类类型,导致编译时,只能调用父类中声明的属性和方法,而子类特有的属性和方法不能调用
- 如何才能调用 子类特有的属性和方法 ?? 向下转型:使用强制类型转换符
关键字instanceof的使用
- a instanceof A:判断对象a是否是类A的实例,如果是返回true,如果不是返回false
- 使用情形:为了避免在向下转型时出现 CLassCastException的异常,我们在向下转型之前,先进行instanceof的判断
- 返回true,就进行向下转型(转型结构如下 A a1 = (A)a;),返回false,不进行向下转型
- 如果 a instanceof A :返回true ,则 a instanceof B :返回true 其中 类B是类A的父类
(2021.1.18这块好难,思路不清晰,绕着绕着就把自己绕晕了
第二遍了 感觉还是不流畅 没有之前知识理解的清楚
第三遍了 感觉是有那么一丝味道了)
多态练习题一
package com.atguigu.java1;
public class FieldMethodTest {
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);//true
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);
}
}
- 若子类重写了父类方法,就意味着子类里定义的方法彻底覆盖了父类里的同名方法,系统将不可能把父类里的方法转移到子类中。(编译看左边 运行看右边)
- 对于实例变量则不存在这样的现象,即使子类里定义了与父类完全相同的实例变量,这个实例变量依然不可能覆盖父类中定义的实例变量。(编译运行都看左边)
多态练习题二
package com.atguigu.java1;
public class InstanceTest {
public static void main(String[] args) {
InstanceTest test = new InstanceTest();
test.method(new Student());
}
public void method(Person e) {
String info = e.getInfo();
System.out.println(info);
if(e instanceof Graduate) {
System.out.println("a graduated student" + "\n" + "a student" + "\n" + "a person");
}else if(e instanceof Student) {
System.out.println("a student" + "\n" + "a person");
}else {
System.out.println("a person");
}
}
}
class Person {
protected String name = "person";
protected int age = 50;
public String getInfo() {
return "Name: " + name + "\n" + "age: " + age;
}
}
class Student extends Person {
protected String school = "pku";
public String getInfo() {
return "Name: " + name + "\nage: " + age + "\nschool: " + school;
}
}
class Graduate extends Student {
public String major = "IT";
public String getInfo() {
return "Name: " + name + "\nage: " + age + "\nschool: " + school + "\nmajor:" + major;
}
}
多态练习题三
定义三个类,父类GeometricObject代表几何形状,子类Circle代表圆形,MyRectangle代表矩形。定义一个测试类GeometricTest,
编写equalsArea方法测试两个对象的面积是否相等(注意方法的参数类型,利用动态绑定技术),
编写displayGeometricObject方法显示对象的面积(注意方法的参数类型,利用动态绑定技术)。
package com.atguigu.java1;
public class GeometricObject {
protected String color;
protected double Weight;
protected GeometricObject() {
}
protected GeometricObject(String color,double weight) {
this.color = color;
this.Weight = weight;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
public double getWeight() {
return Weight;
}
public void setWeight(double weight) {
Weight = weight;
}
public double findArea() {
return 0.0;
}
}
package com.atguigu.java1;
public class Circle extends GeometricObject {
private double radius;
public Circle(String color,double weight,double radius) {
super(color,weight);
this.radius = radius;
}
public double getRadius() {
return radius;
}
public void setRadius(double radius) {
this.radius = radius;
}
@Override
public double findArea() {
return Math.PI*radius*radius;
}
}
package com.atguigu.java1;
public class MyRectangle extends GeometricObject {
private double width;
private double height;
public MyRectangle() {
}
public MyRectangle(double width,double height,String color,double weight) {
super(color,weight);
this.width = width;
this.height = height;
}
public double getWidth() {
return width;
}
public void setWidth(double width) {
this.width = width;
}
public double getHeight() {
return height;
}
public void setHeight(double height) {
this.height = height;
}
public double findArea() {
return width*height;
}
}
package com.atguigu.java1;
public class GeometricTest {
public static void main(String[] args) {
GeometricTest test = new GeometricTest();
Circle c1 = new Circle("red",4,3.5);
MyRectangle m1 = new MyRectangle(4, 5, "blue", 4);
test.displayGeometricObject(c1);
test.displayGeometricObject(m1);
System.out.println("面积是否相等:" +test.equalsArea(c1,m1));
}
public boolean equalsArea(GeometricObject o1, GeometricObject o2) {
return o1.findArea() == o2.findArea();
}
public void displayGeometricObject(GeometricObject o3) {
double area = o3.findArea();
System.out.println("面积是" + area);
}
}
多态练习题四
输出程序结果
package com.atguigu.java;
//考查多态的笔试题目:
public class InterviewTest{
public static void main(String[] args) {
Base base = new Sub();
base.add(1, 2, 3);// sub1
Sub s = (Sub)base;
s.add(1,2,3);// sub2
}
}
class Base {
public void add(int a, int... arr) {
System.out.println("base");
}
}
class Sub extends Base {
public void add(int a, int[] arr) {
System.out.println("sub_1");
}
public void add(int a, int b, int c) {
System.out.println("sub_2");
}
}
Object类的使用
java.lang.Object类
1 Object类是所有Java类的根父类
2 如果在类的声明中未使用extends关键字指明其父类,则默认父类为java.lang.Object类
3 Object类中的功能(属性 方法)就具有通用性
- 属性:无
- 方法:equals() / toString() / getClass() / hashCode() / clone() / finalize() wait()
4 Object类只声明了空参构造器
面试题: == 和 equals() 有什么区别?
== : 运算符
1 可以使用在基本数据类型和引用数据类型中
2 如果比较的是 基本数据类型:比较的是两个变量保存的数据是否相等。(不一定类型要相同)
3 如果比较的是 引用数据类型:比较的是两个对象的地址值是否相同,即两个引用是否指向同一个对象实体
补充: 这个符号使用时,必须保证符号左右两边的变量类型一致。
equals():一个方法,而非运算符
1 只能适用于引用数据类型
2 Object类中equals()的定义:
public boolean equlas(Object obj){
return this == obj;
}
说明:Object类中定义的 equals() 和 == 作用相同
3 像String,Data,File,包装类等都重写了Object类中的equals()方法,重写以后,比较的不是两个引用的地址是否相同,而是比较两个对象的"实体内容"是否相同
4 通常情况下,我们自定义的类如果使用 equals()方法 ,也是比较两个对象的 "实体内容"是否相同。那么,我们就需要对Object类中的equals()进行重写
重写规则:比较两个对象的 "实体内容"是否相同 (注:可以在Eclipse中自动生成)
package com.atguigu.chapter5;
public class Customer {
private String name;
private int age;
public Customer() {
super();
}
public Customer(String name, int age) {
super();
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;
}
/* (non-Javadoc)
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
public boolean equals(Object obj) {
if(this == obj) {
return true;
}
if(obj instanceof Customer) {
Customer cust = (Customer)obj;
//比较两个对象的属性是否相同
if(this.age == cust.age && this.name.equals(cust.name)) {
return true;
}
}
return false;
}
}
package com.atguigu.chapter5;
public class EqualsTest {
public static void main(String[] args) {
Customer cust1 = new Customer("Tom",21);
Customer cust2 = new Customer("Tom",21);
System.out.println(cust1 == cust2);//false
String str1 = new String("atguigu");
String str2 = new String("atguigu");
System.out.println(str1 == str2);//false
//System.out.println(cust1.equals(cust2));//false
System.out.println(cust1.equals(cust2));
System.out.println(str1.equals(str2));//true
}
}
练习题1
编写Order类,有int型的orderId,String型的orderName,相应的getter()和setter()方法,两个参数的构造器,重写父类的equals()方法:public boolean equals(Object obj),并判断测试类中创建的两个对象是否相等。
package com.atguigu.chapter5;
public class Order {
private int orderld;
private String orderName;
public Order() {
super();
}
public Order(int orderld, String orderName) {
super();
this.orderld = orderld;
this.orderName = orderName;
}
public int getOrderld() {
return orderld;
}
public void setOrderld(int orderld) {
this.orderld = orderld;
}
public String getOrderName() {
return orderName;
}
public void setOrderName(String orderName) {
this.orderName = orderName;
}
public boolean equals(Object obj) {
if(this == obj) {
return true;
}
if(obj instanceof Order) {
Order order = (Order)obj;
return this.orderld == order.orderld &&
this.orderName.equals(order.orderName);
}
return false;
}
}
package com.atguigu.chapter5;
public class OrderTest {
public static void main(String[] args) {
Order o1 = new Order(21,"Tom");
Order o2 = new Order(21,"Tom");
System.out.println(o1.equals(o2));
}
}
Object类中toString方法的使用
1 当我们输出一个对象的引用时,实际上就是调用当前对象的 toString()
2 Object类中toString 的定义
public String toString() {
return getClass().getName() + "@" + Integer.toHexString(hashCode());
}
3 像String Data File 包装类等都重写了Object类中toString方法,使得在调用对象的 toString 方法时,返回"实体内容"
4 自定义类也可以重写 toString 方法 可自动实现
package com.atguigu.chapter5;
public class Customer {
private String name;
private int age;
public Customer() {
super();
}
public Customer(String name, int age) {
super();
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;
}
/* (non-Javadoc)
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
public boolean equals(Object obj) {
if(this == obj) {
return true;
}
if(obj instanceof Customer) {
Customer cust = (Customer)obj;
//比较两个对象的属性是否相同
if(this.age == cust.age && this.name.equals(cust.name)) {
return true;
}
}
return false;
}
/* (non-Javadoc)
* @see java.lang.Object#toString()
*/
@Override
public String toString() {
return "Customer[name = " + name + ",age = " + age + "]";
}
}
package com.atguigu.chapter5;
public class ToString {
public static void main(String[] args) {
Customer cust1 = new Customer("Tom",21);
// System.out.println(cust1.toString());//com.atguigu.chapter5.Customer@15db9742
// System.out.println(cust1);//com.atguigu.chapter5.Customer@15db9742
String str = new String("asafa");
System.out.println(str.toString());
System.out.println(cust1.toString());
}
}
练习9
定义两个类,父类GeometricObject代表几何形状,子类Circle代表圆形
package com.atguigu.chapter5;
public class GeometricObject {
protected String color;
protected double weight;
protected GeometricObject() {
color = "white";
weight = 1.0;
}
protected GeometricObject(String color, double weight) {
this.color = color;
this.weight = weight;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
public double getWeight() {
return weight;
}
public void setWeight(double weight) {
this.weight = weight;
}
}
package com.atguigu.chapter5;
public class Circle extends GeometricObject {
private double radius;
public Circle() {
super();
radius = 1.0;
}
public Circle(double radius) {
super();
this.radius = radius;
}
public Circle(double radius,String color,double weight){
this.radius = radius;
this.color = color;
this.weight = weight;
}
public double getRadius() {
return radius;
}
public void setRadius(double radius) {
this.radius = radius;
}
public double findArea() {
return Math.PI*radius*radius;
}
public boolean equals(Object obj) {
if(this == obj) {
return true;
}
if(obj instanceof Circle) {
Circle cir = (Circle)obj;
return this.radius == cir.radius;
}
return false;
}
public String toString() {
return "Circle [radius : " + this.radius + "]";
}
}
包装类的使用
Java中的JUnit单元测试
步骤 1 选中当前工程 - - 右键选择:build path – add libraries – JUnit
2 创建 Java类 进行单元测试
此时Java类要求:此类是public的 并且此类提供无参的构造器
3 此类中声明单元测试方法
此时的单元测试方法:方法的权限是public,没有返回值,没有形参
4 此单元测试方法上需要声明注解:@Test,并在单元测试类中导入
5 声明单元测试方法以后,可以在方法体内测试相关的代码
6 左键双击单元测试方法名,右键:run as - JUnit Test
具体工程实践中,直接输入@Test 快速导入即可
package com.atguigu.chapter5;
import org.junit.Test;
public class JUnit {
int number = 10;
public void show() {
System.out.println("show...");
}
@Test
public void testEquals() {
String s1 = "asd";
String s2 = "asdf";
System.out.println(s1.equals(s2));
System.out.println(number);
show();
}
}
包装类的使用
1 java提供了8种基本数据类型对应的包装类,使得基本数据类型的变量具有类的特征
2 基本数据类型,包装类和String类之间的转化
package com.atguigu.chapter5;
import org.junit.Test;
public class WarpperTest {
// 基本数据类型 --> 包装类:调用包装类的构造器
@Test
public void test1() {
int num1 = 10;
Integer in1 = new Integer(num1);
System.out.println(in1.toString());//10
Integer in2 = new Integer(55);//55
Float f1 = new Float(12.3);
Float f2 = new Float("12.3");
System.out.println(f1);//12.3
System.out.println(f2);//12.3
Boolean b2 = new Boolean("TRue");
System.out.println(b2);//true
boolean b3 = new Boolean("true123");
System.out.println(b3);// false
}
//包装类 --> 基本数据类型:调用包装类的 xxxValue() 方法
@Test
public void test2() {
Integer in1 = new Integer(12);
int i1 = in1.intValue();
System.out.println(i1);
Float f1 = new Float(12.3);
float ff1 = f1.floatValue();
System.out.println(ff1);
}
// JDK5.0 : 自动装箱 与 自动插箱
@Test
public void test3() {
//自动装箱
int num2 = 10;
Integer in2 = num2;
//自动拆箱
int num3 = in2;
System.out.println(num3);
}
//基本数据类型,包装类 --> String类型:调用String重载的valueof(xxx)
@Test
public void test4() {
//方式1 : 连接运算
int num1 = 10;
String str1 = num1 + "";
//方式2:
float f1 = 12.3f;
String str2 = String.valueOf(f1);
System.out.println(str2);
Double d1 = 12.456;
String str3 = String.valueOf(d1);
System.out.println(str3);
}
//String类型 --> 基本数据类型,包装类 : 调用包装类的parseXxx(String s)
@Test
public void test5() {
String str1 = "123";
int num1 = Integer.parseInt(str1);
System.out.println(num1);
String str2 = "true";
boolean b2 = Boolean.parseBoolean(str2);
System.out.println(b2);
}
}
包装类(Wrapper)的使用 面试题
package com.atguigu.chapter5;
import org.junit.Test;
public class InterviewTest {
@Test
public void test1() {
Object o1 = true ? new Integer(1) : new Double(2.0);
System.out.println(o1);// 1.0
}
@Test
public void test2() {
Object o2;
if (true)
o2 = new Integer(1);
else
o2 = new Double(2.0);
System.out.println(o2);// 1
}
@Test
public void test3() {
Integer i = new Integer(1);
Integer j = new Integer(1);
System.out.println(i == j);//false
//Integer 内部定义了IntegerCache结构,该结构中定义了Integer[]
//保存了从-128到127范围的整数,使用自动装箱的方式,给Integer赋值时
//假如范围在-128到127范围内,可直接调用,不用再去new了 目的:提高效率
Integer m = 1;
Integer n = 1;
System.out.println(m == n);//true
Integer x = 128;
Integer y = 128;
System.out.println(x == y);//false
}
}
练习10
利用Vector代替数组处理:从键盘读入学生成绩(以负数代表输入结束),找出
最高分,并输出学生成绩等级。
- 提示:数组一旦创建,长度就固定不变,所以在创建数组前就需要知道它的
长度。而向量类java.util.Vector可以根据需要动态伸缩。 - 创建Vector对象:Vector v=new Vector();
- 给向量添加元素:v.addElement(Object obj); //obj必须是对象
- 取出向量中的元素:Object obj=v.elementAt(0);
注意第一个元素的下标是0,返回值是Object类型的 - 计算向量的长度:v.size();
- 若与最高分相差10分内:A等;20分内:B等;30分内:C等;其它:D等
package com.atguigu.chapter5;
import java.util.Scanner;
import java.util.Vector;
public class ScoreTest {
public static void main(String[] args) {
//1.实例化Scanner
Scanner scan = new Scanner(System.in);
//2.创建Vector对象
Vector v=new Vector();
//3.循环添加 Vector元素
int max = 0;
for(;;) {
System.out.print("请输入学生成绩:");
int score = scan.nextInt();
if(score < 0) {
break;
}
if(score > 100) {
System.out.println("成绩输入非法,请重新输入");
continue;
}
// JDK5.0 之前
//Integer inScore = new Integer(score);
//v.addElement(inScore);
//JDK5.0 之后
v.addElement(score);
if(max < score) {
max = score;
}
}
//遍历 Vector
for(int i = 0; i < v.size();i++) {
Object obj=v.elementAt(i);
Integer inScore = (Integer)obj;
int Score = inScore;
String level;
int temp = max - Score;
if(temp <= 10) {
level = "A";
}else if(temp <= 20) {
level = "B";
}else if(temp <= 30) {
level = "C";
}else {
level = "D";
}
System.out.println("student-" + i + " score is " +
Score + ",level is " + level);
}
}
}
参考资料
这一节还行,就是多态那里有点没太懂