5.面向对象习题(中)

目录

一、概念

1.方法的重写

1.1如果现在父类的一个方法定义成private访问权限,在子类中将此方

        法声明为default访问权限,那么这样还叫重写吗?

1.2方法的重写(override/overwrite)的具体规则有哪些? 

2.super调用构造器,有哪些具体的注意点

3.面向对象特征之三:多态性

3.1什么是多态性?什么是虚拟方法调用?

3.2一个类可以有几个直接父类?

3.3问题一:编译通过运行时不通过

3.4问题二:编译通过,运行时也通过

3.5问题三:编译不通过

3.6如何实现向下转型?需要注意什么问题?如何解决此问题?

4.多态性:关键字instanceof

5.Object类的使用练习

6.包装类(Wrapper)的使用

6.1.如下两个题目输出结果相同吗?各是什么

6.2:面试思考题:Integer内部类IntegerCache的Integer[]数组范围【-128,127】使用

7. == 和 equals()有何区别?

8. 重写其equals()方法:目的:比较两个对象的实体内容是否相等

9.写出8种基本数据类型及其对应的包装类

10.基本数据类型、包装类与String三者之间如何转换

二、编程

1.继承性

1.1定义类Kids继承ManKind,定义类KidsTest访问其父类的成员变量及方法

1.2计算圆的面积和圆柱的体积

2.方法的重写

2.1.修改练习1.1中定义的类Kids,在Kids中重新定义employeed()方 法,覆盖父类ManKind中定义的employeed()方法,输出“Kids should study and no job.”

3.类的继承:关键字:super

4、在下面的代码结构中:使用关键字:this,super;方法的重写;继承;

5.面向对象特征之三:多态性

5.1多态性举例:AnimalTest类,Cat类,Dog类

5.2练习:基本操作:子类继承父类

 5.3.基本操作:建立InstanceTest 类,在类中定义方法method(Person e);

5.4几何图形

6.多态是编译时行为还是运行时行为? 如何证明?

7.Object类:equals()

7.1编写Order类,重写父类的equals()方法:并判断测试类中创建的两个对象是否相等

7.2请根据以下代码自行定义能满足需要的MyDate类:equals()重写

8、Object类,toString()方法

8.1、面试题:下列输出结果是多少?数组int,char,double,String;toString()在类的对象中使用

9、Object类:重写toString(),equals()方法。几何图形问题

10. 包装类(Wrapper)的使用:利用Vector代替数组处理:从键盘读入学生成绩(以负数代表输入结束),找出最高分,并输出学生成绩等级。


一、概念

1.方法的重写

1.1如果现在父类的一个方法定义成private访问权限,在子类中将此方

法声明为default访问权限,那么这样还叫重写吗?

答:不叫(no)

        原因:子类重写的方法的权限修饰符不小于父类被重写的方法的权限修饰符
                          >特殊的:
子类不能重写父类中声名为private权限的方法

1.2方法的重写(override/overwrite)的具体规则有哪些? 

1.方法名、形参列表:子类重写的方法的方法名和形参列表与父类被重写的方法的方法名和形参

                                    列表相同

2.权限修饰符:子类重写的方法的权限修饰符不小于父类被重写的方法的权限修饰符

                          >特殊的:子类不能重写父类中声名为private权限的方法

3.返回值类型:>父类被重写的方法的返回值类型是void,则子类重写的方法的返回值类型只能

                                是void

                         >父类被重写的方法的返回值类型是A类型,则子类重写的方法的返回值类型可

                                以是A类或A类的子类。

                         >父类被重写的方法的返回值类型是基本数据类型(比如:double),则子类重

                               写的方法的返回值必须是相同的基本数据类型(必须也是double)

4.抛出的异常:子类重写的方法抛出的异常类型不大于父类被重写的方法抛出的异常类型

2.super调用构造器,有哪些具体的注意点

this(形参列表):本类重载的其它的构造器

super(形参列表):调用父类中指定的构造器

super形如this

1 、我们可以在子类的构造器中显式的使用"super(形参列表)"的方式,调用父类中声明的指定的构造器
2 、"super(形参列表)"的使用,必须声明在子类构造器的首行
3 、我们在类的构造器中,针对于"this(形参列表)"或"super(形参列表)"只能二选一,不能同时出现
4、 在构造器的首行没有显式的声明"this(形参列表)"或"super(形参列表)",则默认调用的是父类中空参的构造器:super().
5、 在类的多个构造器中,至少有一个类的构造器中使用了"super(形参列表)",调用父类中的构造器。

3.面向对象特征之三:多态性

3.1什么是多态性?什么是虚拟方法调用?

对象的多态性:父类的引用指向子类的对象(子类的对象赋给父类的引用)

多态的使用:虚拟方法调用

有了对象的多态性以后,我们在编译期,只能调用父类中声明的方法,我们实际执行的是子类重写父类的方法。

     总结:编译,看左边。运行,看右边。

Person p = new Man();

p.eat();

调用方法时,编译时看左边,运行时看右边。

3.2一个类可以有几个直接父类?

只有一个

一个父类可有多少个子类?(多个

子类能获取直接父类的父类中的结构吗?(可以

子类能否获取父类中private权限的属性或方法?(可以的)

3.3问题一:编译通过运行时不通过

举例一:Man类与Woman类同为Person的子类
        Person p3 = new Woman();
        Man m3 = (Man)p3;

运行出现ClassCastException的异常(类型转换异常),只有在多态性Person p3 = new Man();的情况下,才能实现,父类赋给子类。正常情况下,只能子类赋给父类。

举例二:Man类与Woman类同为Person的子类

       Person p4 = new Person();
       Man m4 = (Man)p4;

运行出现ClassCastException的异常(类型转换异常)Man是Person的子类,且并没有虚拟方法调用,对象p4的实例为new Person(),new的是Person是Man的父类,所以无法使用向下转型(相当于强制转换类型)

3.4问题二:编译通过,运行时也通过

前提:Man类与Woman类同为Person的子类

        Object obj = new Woman();
        Person p = (Person)obj;
        Woman w2 = (Woman)obj;

Object 是Person的父类,Person是Woman的父类,Object相当于是Woman类的间接父类。虚拟方法调用,将子类Woman的实例赋给Object的引用对象(向上转型:多态)
Object类可以强转成(子类)Woman类(向下转型(相当于强制转换类型)),Person类是Woman的父类,因此可以强转成Woman的父类Person。所以Person p = (Person)obj;不为错。但是,若是将Perosn类(父类)的实例赋给了对象obj那么,Object类不能强转为子类Woman,只能强转为父类Person

3.5问题三:编译不通过

编译不通过:没有子父类继承关系是无法进行强转的

//Type mismatch: cannot convert from Woman to Man

         Man m5 = new Woman();

//Type mismatch: cannot convert from Date to String 类型不匹配:无法从日期转换为字符串

        String str = new Date();

Man类与Woman没有子父类关系,无法编译通过,只有子父类关系时,才能将子类实例化赋给父类的对象,只有将子类实例化赋给父类的对象,父类才能强转将父类的实例化赋给子类的对象。

//编译通过:

        Object o = new Date();
        String str1 = (String)o; 

3.6如何实现向下转型?需要注意什么问题?如何解决此问题?

注:多态为向上转型

Person p = new Man();

使用强转符:(),实现向下转型。

Man m = (Man)p;

问题:可能出现ClassCastException异常。

解决方式:使用instanaceof在进行向下转型前判断:

           If(p instanceof Man){

                        Man m = (Man)p;

                }

 

4.多态性:关键字instanceof

a instanceof A:判断对象a是否为类A的实例,如果是,返回true。如果不是,返回false;

如果a instanceof A返回true,则a instanceof B也会返回true
>其中,类B是类A的父类。

        Person p2 = new Man();



        Man m1 = p2;//只能由子类赋给父类,不能父类赋给子类
		//向下转型,使用强制类型转换符
		Man m1 = (Man)p2;
		m1.earnMoney();
		
		m1.isSmoking = true;

//a instanceof A:判断对象a是否为类A的实例,如果是,返回true。如果不是,返回false;
//如果a instanceof A返回true,则a instanceof B也会返回true
//>其中,类B是类A的父类。

        if(p2 instanceof Woman) {
			Woman w1 = (Woman)p2;
			w1.goShopping();
			System.out.println("*****Woman*******");
		}
		if(p2 instanceof Man) {
			Man m2 = (Man)p2;
			m2.earnMoney();;
			System.out.println("*****Man*******");
		}
		if(p2 instanceof Person) {
			System.out.println("******Person********");
		}
		if(p2 instanceof Object) {
			System.out.println("***********Object************");



        Woman wman = new Woman();
		if(wman instanceof Woman) {
			System.out.println("wman");
		}
		if(wman instanceof Person) {
			System.out.println("Person wman");
		}    

5.Object类的使用练习

int it = 65;
float fl = 65.0f;
System.out.println(“65 65.0f 是否相等? ” + (it == fl)); //true
----------------------------------------------------------------------------------------------------
char ch1 = 'A'; char ch2 = 12;
System.out.println("65 'A' 是否相等? " + (it == ch1));//true
System.out.println(“12 ch2 是否相等? " + (12 == ch2));//true
---------------------------------------------------------------------------------------------------
String str1 = new String("hello");
String str2 = new String("hello");
System.out.println("str1 str2 是否相等? "+ (str1 == str2));//false
---------------------------------------------------------------------------------------------------
System.out.println("str1 是否 equals str2 "+(str1.equals(str2)));//true
----------------------------------------------------------------------------------------------------
System.out.println(“hello” == new java.util.Date()); // 编译不通过

6.包装类(Wrapper)的使用

6.1.如下两个题目输出结果相同吗?各是什么

Object o1 = true ? new Integer(1) : new Double(2.0);
System. out .println( o1 ); // 1.0
---------------------------------------------------------------------
原因:
1.三元运算符,在编译时":"前后的 表达式1和表达式2的返回值类型要相同;所以还没有经过条件表达式判断,表达式1已经自动类型提升,Integer(1)的int类型自动提升为double类型
               
2.条件表达式为true,运行表达式1:Object o1 = new Integer(1);是一个 多态编译看左边,运行看右边。
编译:o1.toString(),运行:new Integer(1).toString();
3. 包装类重写了Object类中的toString()方法,返回值为“实体内容”;
最后的返回值为double类型的 1.0;
Object o2 ;
if ( true )
o2 = new Integer(1);
else
o2 = new Double(2.0);
System. out .println( o2 ); // 1
-----------------------------------------------------------------------
原因:
1.条件表达式为true,执行表达式1:Object o2 = new Integer(1);是一个 多态编译看左边,运行看右边。
编译:o1.toString(),运行:new Integer(1).toString();
2.Integer(1)是一个 包装类重写了Object类中的toString()方法,返回值为“实体内容”
 最后的返回值为int类型的 1;

代码实现:JUnit单元测试

package com.atguigu.java2;

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
		/*
		 * 原因:1.三元运算符,在编译时":"前后的表达式1和表达式2的返回值类型要相同,Integer(1)的int类型自动提升为double类型
		 *         所以还没有经过条件表达式判断,表达式1已经自动类型提升
		 *      2.条件表达式为true,运行表达式1:Object o1 = new Integer(1);是一个多态,编译看左边,运行看右边。
		 *         编译:o1.toString(),运行:new Integer(1).toString();包装类重写了Object类中的toString()方法,返回值为“实体内容”;
		 *         最后的返回值为double类型的 1.0;
		 */
	}
	@Test
	public void test2() {
		Object o2;
		if (true) {
			o2 = new Integer(1);//表达式1
		}else {
		o2 = new Double(2.0);//表达式2
		}
		System.out.println(o2);//1
		/*
		 * 条件表达式为true,执行表达式1:Object o2 = new Integer(1);是一个多态,编译看左边,运行看右边。
		 * 编译:o1.toString(),运行:new Integer(1).toString();包装类重写了Object类中的toString()方法,返回值为“实体内容”
		 * 最后的返回值为int类型的 1;
		 */
		
	}
}

6.2:面试思考题:Integer内部类IntegerCache的Integer[]数组范围【-128,127】使用

public void method1() {
        //①
        Integer i = new Integer(1);
        Integer j = new Integer(1);
        System. out .println( i == j );//false
        //②
        Integer m = 1;
        Integer n = 1;
        System. out .println( m == n );//true
        //③
        Integer x = 128;
        Integer y = 128;
        System. out .println( x == y );//false
}

--------------------------------------------------------------------------------------------------------------

原因:

        Integer类中定义了一个内部类:IntegerCacheIntegerCache中定义了Integer[]数组,保存了从【-128,127】范围内的整数,方便我们使用。如果我们使用自动装箱的方式,给Integer赋值的范围在-128~127范围内时,可以直接使用数组中的元素,不用再去new了。

目的:提高效率,在这个范围内的数使用的次数多;

--->同时,Integer[]数组不会被回收,能够一直使用,在这个范围内所有对象调用的都是一个内存空间的整数,地址值相同。
因此:①中是用new了两个对象,所以i,j的地址值不同:i != j;

           ②中m,n两个对象是制动装箱,调用的地址值相同:m == n;

           ③中x,y两个对象的值超出了数组范围,需要new新的对象,地址值不相同:x != y;

@Test
	public void tesst3() {
		Integer i = new Integer(1);
		Integer j = new Integer(1);
		System.out.println(i == j);//false
		
		Integer m = 1;
		Integer n = 1;
		System.out.println(m == n);//true
		/*
		 * 原因:Integer类中定义了一个内部类:IntegerCache,IntegerCache中定义了Integer[]数组,
		 * 保存了从【-128,127】范围内的整数,方便我们使用。如果我们使用自动装箱的方式,给Integer赋值的范围在
		 * -128~127范围内时,可以直接使用数组中的元素,不用再去new了。目的:提高效率,在这个范围内的数使用的次数多;
		 * 同时,Integer[]数组不会被回收,能够一直使用。
		 * 因此:m,n两个对象调用的地址值相同:m == n;x,y两个对象的值超出了数组范围,需要new新的对象,地址值不相同:x != y;
		 */
		
		Integer x = 128;//相当于new了一个Integer对象
		Integer y = 128;//相当于new了一个Integer对象
		System.out.println(x == y);//false;

7. == 和 equals()有何区别?

==:比较运算符

1. 可以使用在基本数据类型变量和引用数据类型变量中

2. 如果比较的是基本数据类型变量,比较两个变量保存的数据是否相等。(不一点类型相同)

如果比较的是引用数据类型变量,比较两个对象的地址值是否相同。即两个引用是否指向同一个对象实体。

·   补充: == 符号使用时,必须保证符号左右两边的变量类型一致。

equals()方法的使用:

1.是一个方法,而非运算符

2.只能够适用于引用数据类型

3.Object类中equals()的定义:

  public boolean equals(Object obj) {

          return (this == obj);

     }

说明:Object类中定义的equals()和 == 的作用是相同的,比较两个对象的地址值是否相同,即两个引用是否指向同一个对象实体

4.想String、Date、File、包装类等都重写了Object类中的equals()方法,重写以后,比较的不是两个引用的地址值是否相同,而是比较两个对象的“实体内容”是否相同

5.通常情况下,我们自定义的类如果使用equals()的话,也通常是比较两个对象的 “实体内容”是否相同。

  那么,我们就需要对Object类中的equals()方法进行重写

  重写的原则,比较两个对象的实体内容是否相同。

8. 重写其equals()方法:目的:比较两个对象的实体内容是否相等

  1. class User{

String name;

int age;

        //重写其equals()方法:比较两个对象的实体内容是否相等

        public boolean equals(Object obj){

                If(this == obj){//判断两个地址值是否相等

                        return true;

                }

                If(obj instanceof User){//判断是否为User的实例

                        User u = (User)obj;

                        return this.age == u.age && this.name.equals(u.name);

                }

                return false;

        }

}

 9.写出8种基本数据类型及其对应的包装类

 10.基本数据类型、包装类与String三者之间如何转换

JDK 5.0新特性:自动装箱与自动拆箱

        自动装箱:本数据类型 --->包装类

                int num2 = 11;

                Integer in2 = num2;//自动装箱

                System.out.println(in2);//11

        自动拆箱:包装类 --->基本数据类型

                Integer in1 = new Integer(12);

                int num3 = in1;//自动拆箱

                System.out.println(num3);//12

基本数据类型、包装类--->String类型:调用String重载的valueOf(Xxx xxx)

        Double d1 = new Double(12.4);

        String str3 = String.valueOf(d1);

        System.out.println(str3);//"12.4"

String类型---->基本数据类型、包装类:调用包装类的parseXxx()

        String str = "123";

        int num2 = Integer.parseInt(str);

        System.out.println(num2+1);//124

        //错误情况:NumberFormatException: For input string: "123a"

        // String s = "123a";

        // int num1 = Integer.parseInt(s);

        // System.out.println(num1);

        String str2 = "true";

        Boolean b1 = Boolean.parseBoolean(str2);

        System.out.println(b1);//true

二、编程

1.继承性

1.1定义类Kids继承ManKind,定义类KidsTest访问其父类的成员变量及方法

(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 ,用该对象访问
其父类的成员变量及方法。
结果:
编写代码:
(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)
package com.atguigu.exer;
/*
 * 成员变量int sex和int salary;
 * 方法void manOrWoman():根据sex的值显示“man”(sex==1)或者“woman”(sex==0);
 * 方法void employeed():根据salary的值显示“no job”(salary==0)或者“ job”(salary!=0)。
 * 
 * 
 */

import java.util.Scanner;
/**
 * 父类
 * @author Administrator
 *
 */
public class ManKind {
	private int sex; //性别
	private int salary; //薪水
	
	
	public ManKind() {
		
	}
	public ManKind(int sex, int salary) {
		
		this.sex = sex;
		this.salary = salary;
	}
	/**
	 * 根据sex的值显示“man”(sex==1)或者“woman”(sex==0);
	 */
	public void manOrWoman() {
		if(this.sex == 1) {
			System.out.println("man");
		}else if(sex == 0) {
			System.out.println("woman");
		}
	}
	/**
	 * 根据salary的值显示“no job”(salary==0)或者“ job”(salary!=0)。
	 */
	public void employeed() {
		if(this.salary ==0) {
			System.out.println("no job");
		}else {
			System.out.println("job");
		}
		//或 三元运算
//		String jobInfo = (salary == 0)? "no job":"job";
//		System.out.println(jobInfo);
		
	}
	
	public void setSex(int sex) {
		this.sex = sex;
	}
	public int getSex(){
		return sex;
	}
	public int getSalary() {
		return salary;
	}
	public void setSalary(int salary) {
		this.salary = salary;
	}
	
}
(2) 定义类 Kids 继承 ManKind ,并包括
>成员变量 int yearsOld
>方法 printAge() 打印 yearsOld 的值。
(3) 定义类 KidsTest ,在类的 main 方法中实例化 Kids 的对象 someKid ,用该对象访问
其父类的成员变量及方法。
package com.atguigu.exer;
/*
 * 定义类Kids继承ManKind
 * 成员变量int yearsOld;
 * 方法printAge()打印yearsOld的值。
 */
public class Kids extends ManKind{
	
	private int yearsOld;
	
	public Kids() {
		
	}

	public Kids(int yearsOld) {
		
		this.yearsOld = yearsOld;
	}

	public void printAge() {
		System.out.println("I am "+yearsOld+" years old");
	}

	public int getYearsOld() {
		return yearsOld;
	}

	public void setYearsOld(int yearsOld) {
		this.yearsOld = yearsOld;
	}
	
}
(3) 定义类 KidsTest ,在类的 main 方法中实例化 Kids 的对象 someKid ,用该对象访问
其父类的成员变量及方法。
package com.atguigu.exer;
/*
 * 在类的main方法中实例化Kids的对象someKid,
 * 用该对象访问其父类的成员变量及方法
 */
public class KidsTest {
	public static void main(String[] args) {
		Kids someKid = new Kids(12);
		
		someKid.printAge();//打印年龄
		
		someKid.setSex(1);//给sex赋值
		someKid.setSalary(0);//给薪水赋值
		
		someKid.manOrWoman();//输出sex
		someKid.employeed();//输出job/no job
	}
}

1.2计算圆的面积和圆柱的体积

 注:子类 ---->父类:Circle:父类,Cylinder:子类

Circle类

package com.atguigu.exer1;

import java.awt.geom.PathIterator;
/*
 * 圆
 */
public class Circle {
	private double radius;//半径
	
	public Circle() {
		radius = 1.0;
	}

	public double getRadius() {
		return radius;
	}

	public void setRadius(double radius) {
		this.radius = radius;
	}
	//返回圆的面积
	public double findArea() {
		return Math.PI*radius*radius;
	}
	
}

Cylinder类

package com.atguigu.exer1;

/*
 * 圆柱
 */
public class Cylinder extends Circle{
	private double length;//高

	public Cylinder() {
		length=1.0;
	}

	public double getLength() {
		return length;
	}

	public void setLength(double length) {
		this.length = length;
	}
	//返回圆柱的体积
	public double findeVolume() {
		return findArea()*getLength();
	
	}
	
	
	
}

CylinderTest类

package com.atguigu.exer1;

public class CylinderTest {
	public static void main(String[] args) {
		Cylinder volume = new Cylinder();
		volume.setRadius(2.1);
		volume.setLength(3.4);
		double volue = volume.findeVolume();
		System.out.println("圆柱的体积:"+volue);
		
		double area = volume.findArea();
		System.out.println("底面圆的面积:"+area);
		
		
	}
}

2.方法的重写

2.1.修改练习1.1中定义的类Kids,在Kids中重新定义employeed()方 法,覆盖父类ManKind中定义的employeed()方法,输出“Kids should study and no job.”

结果:

Kids类:

package com.atguigu.exer;
/*
 * 定义类Kids继承ManKind
 * 成员变量int yearsOld;
 * 方法printAge()打印yearsOld的值。
 */
public class Kids extends ManKind{
	
	private int yearsOld;
	
	public Kids() {
		
	}

	public Kids(int yearsOld) {
		
		this.yearsOld = yearsOld;
	}

	public void printAge() {
		System.out.println("I am "+yearsOld+" years old");
	}

	public int getYearsOld() {
		return yearsOld;
	}

	public void setYearsOld(int yearsOld) {
		this.yearsOld = yearsOld;
	}
    //employeed()方法的重写
	public void employeed() {
		System.out.println("Kids should study and no job");
	}
	
}

3.类的继承:关键字:super

1 、写一个名为 Account 的类模拟账户。该类的属性和方法如下图所示。该类包括的属性:
账号 id ,余额 balance ,年利率 annualInterestRate ;包含的方法:访问器方法( getter
setter 方法),返回月利率的方法 getMonthlyInterest() ,取款方法 withdraw() ,存款方法
deposit()

写一个用户程序测试 Account 类。在用户程序中,创建一个账号为 1122 、余额为 20000
年利率 4.5% Account 对象。使用 withdraw 方法提款 30000 元,并打印余额。
再使用 withdraw 方法提款 2500 元,使用 deposit 方法存款 3000 元,然后打印余额和月利
率。
提示: 在提款方法 withdraw 中,需要判断用户余额是否能够满足提款数额的要求,如果不
能,应给出提示。
运行结果如图所示:

package com.atguigu.exer2;
/*
 * 写一个名为 Account 的类模拟账户。该类的属性和方法如下图所示。
 * 该类包括的属性:账号 id,余额 balance,年利率 annualInterestRate;
 * 包含的方法:访问器方法(getter 和setter 方法),
 * 			  返回月利率的方法 getMonthlyInterest(),
 * 			  取款方法 withdraw(),
 * 			  存款方法deposit()。
 * 
 * 
 */
public class Account {
	private int id;//账户
	private double balance;//余额
	/*
	 * 父类Account的属性balance被设置为private,但在子类CheckAccount的withdraw
	 * 方法中需要修改它的值,因此应修改父类的 balance 属性,定义其为 protected。
	 */
	//protected double balance;
	private double annuallnterestRate;//年利率
	
//	public Account() {
//		
//	}
	public Account(int id,double balance,double annuallnterestRate) {
		super();
		this.id = id;
		this.balance = balance;
		this.annuallnterestRate = annuallnterestRate;
	}
	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 getAnnuallnterestRate() {
		return annuallnterestRate;
	}
	public void setAnnuallnterestRate(double annuallnterestRate) {
		this.annuallnterestRate = annuallnterestRate;
	}
	
	/*
	 * 返回月利率
	 */
	public double getMonthlyInterest() {
		
		
		return this.annuallnterestRate/12;
	}
	/*
	 * 取款方式
	 */
	public void withdraw (double amount) {
//		if(balance < amount) {
//			System.out.println("余额不足!");
//			
//		}else {
//			balance -= amount;
		//或
		if(balance >= amount) {
			balance -= amount;
			return;//跳出方法
		}
		System.out.println("余额不足!");
	}
	/*
	 * 存款方式
	 * 
	 */
	public void deposit (double amount) {
		if(amount > 0) {
			balance += amount;
//			System.out.println("你的账户余额为:"+balance);
		}
	}
	
	/*
	 * 写一个用户程序测试 Account 类。
	 * 在用户程序中,创建一个账号为 1122、余额为 20000、年利率 4.5%的 Account 对象。
	 * 使用 withdraw 方法提款 30000 元,并打印余额。
	 * 再使用 withdraw 方法提款 2500 元,
	 * 使用 deposit 方法存款 3000 元,
	 * 然后打印余额和月利率。
	 */
//	public static void main(String[] args) {
//		Account account = new Account(1122, 20000, 0.045);
//		account.withdraw(30000);
//		
//		account.withdraw(2500);
//		account.deposit(3000);
//		System.out.println("月利率:"+account.getMonthlyInterest()); 
//	}
}
package com.atguigu.exer2;

public class AccountTest {
	public static void main(String[] args) {
		Account account = new Account(1122, 20000, 0.045);
		account.withdraw(30000);
		System.out.println("你的账户余额为"+account.getBalance());
		account.withdraw(2500);
		System.out.println("你的账户余额为"+account.getBalance());
		account.deposit(3000);
		System.out.println("你的账户余额为"+account.getBalance());
		System.out.println("月利率:"+(account.getMonthlyInterest()*100)+"%"); 
	}
}
2.创建 Account 类的一个子类 CheckAccount 代表可透支的账户,该账户中定义一个属性
overdraft 代表可透支限额。在 CheckAccount 类中重写 withdraw 方法,其算法如下:
如果(取款金额 < 账户余额),
        可直接取款
如果(取款金额 > 账户余额),
       计算需要透支的额度
       判断可透支额 overdraft 是否足够支付本次透支需要,如果可以
       将账户余额修改为 0,冲减可透支金额
如果不可以
        提示用户超过可透支额的限额
要求: 写一个用户程序测试 CheckAccount 类。在用户程序中,创建一个账号为 1122 、余
额为 20000 、年利率 4.5% ,可透支限额为 5000 元的 CheckAccount 对象。
使用 withdraw 方法提款 5000 元,并打印账户余额和可透支额。
再使用 withdraw 方法提款 18000 元,并打印账户余额和可透支额。
再使用 withdraw 方法提款 3000 元,并打印账户余额和可透支额。
提示:
1 ) 子类 CheckAccount 的构造方法需要将从父类继承的 3 个属性和子类自己的属性全
部初始化。
(2) 父类 Account 的属性 balance 被设置为 private ,但在子类 CheckAccount withdraw
方法中需要修改它的值,因此应修改父类的 balance 属性,定义其为 protected
运行结果如下图所示:

package com.atguigu.exer2;
/*
 * 创建 Account 类的一个子类 CheckAccount 代表可透支的账户,
 * 该账户中定义一个属性overdraft 代表可透支限额。
 * 在 CheckAccount 类中重写 withdraw 方法
 * 
 * 提示:
 *(1) 子类 CheckAccount 的构造方法需要将从父类继承的 3 个属性和子类自己的属性全部初始化。
 *(2) 父类Account的属性balance被设置为private,但在子类CheckAccount的withdraw
 *	      方法中需要修改它的值,因此应修改父类的 balance 属性,定义其为 protected。
 */
public class CheckAccount extends Account{
	
	private double getOverdraft;//可透支限额
	
//	public ChieckAccount() {
//		
//	}
//	public ChieckAccount(double overdraft) {
//		this.overdraft = overdraft;
//	}
	public CheckAccount(int id,double balance,double annuallnterestRate,double overdraft) {
		super(id,balance,annuallnterestRate);
		this.getOverdraft = overdraft;
	}
	
	public double getOverdraft() {
		return getOverdraft;
	}

	public void setOverdraft(double overdraft) {
		this.getOverdraft = overdraft;
	}

	/**
	 * 如果(取款金额<账户余额),
	 * 		可直接取款
	 * 如果(取款金额>账户余额),
	 * 		计算需要透支的额度
	 * 		判断可透支额 overdraft 是否足够支付本次透支需要,如果可以
	 * 		将账户余额修改为 0,冲减可透支金额
	 * 如果不可以
	 * 		提示用户超过可透支额的限额
	 */
	 // 取款方式
	public void withdraw (double amount) {
		double balance = getBalance();
		if(amount <= balance) {
			//方式三:
			balance -= amount;
			setBalance(balance);
			//方式一:
			//setBalance(getBalance() - amount);
			//方式二:
			//super.withdraw(amount);
			
//			System.out.println("你的账户余额为:"+getBalance());
//			System.out.println("您的可透支余额为:"+this.overdraft);
		}else {
			double overdraft = amount - balance;//需要透支的金额
			if(this.getOverdraft > overdraft) {//透支额度+余额足够消费
				setBalance(0);//余额归0
				//或:
				//super.withdraw(getBalance());//取光余额
				//System.out.println("你的账户余额为:"+getBalance());
				this.getOverdraft -= overdraft;
				//System.out.println("您的可透支余额为:"+this.overdraft);
				
				
			}else {
				System.out.println("超过可透支额的限额!");
			}
		}
	}
	/*
	 * 写一个用户程序测试 CheckAccount 类。
	 * 在用户程序中,创建一个账号为 1122、余额为 20000、年利率 4.5%,
	 * 可透支限额为 5000 元的 CheckAccount 对象。
	 * 使用 withdraw 方法提款 5000 元,并打印账户余额和可透支额。
	 * 再使用 withdraw 方法提款 18000 元,并打印账户余额和可透支额。
	 * 再使用 withdraw 方法提款 3000 元,并打印账户余额和可透支额。
	 */
//	public static void main(String[] args) {
//		CheckAccount check = new CheckAccount(1122, 20000, 0.045, 5000);
//		
//		check.withdraw(5000);
//		System.out.println("您的账户余额为:"+check.getBalance());
//		System.out.println("您的可透支额为:"+check.overdraft);
//		System.out.println();
//		check.withdraw(18000);
//		System.out.println("您的账户余额为:"+check.getBalance());
//		System.out.println("您的可透支额为:"+check.overdraft);
//		System.out.println();
//		check.withdraw(3000);
//		System.out.println("您的账户余额为:"+check.getBalance());
//		System.out.println("您的可透支额为:"+check.overdraft);
//	}
//	
	
	
}
package com.atguigu.exer2;
/*
 * 写一个用户程序测试 CheckAccount 类。
 * 在用户程序中,创建一个账号为 1122、余额为 20000、年利率 4.5%,
 * 可透支限额为 5000 元的 CheckAccount 对象。
 * 使用 withdraw 方法提款 5000 元,并打印账户余额和可透支额。
 * 再使用 withdraw 方法提款 18000 元,并打印账户余额和可透支额。
 * 再使用 withdraw 方法提款 3000 元,并打印账户余额和可透支额。
 */
public class CheckAccountTest {
	public static void main(String[] args) {
		CheckAccount check = new CheckAccount(1122, 20000, 0.045, 5000);
		
		check.withdraw(5000);
		System.out.println("您的账户余额为:"+check.getBalance());
		System.out.println("您的可透支额为:"+check.getOverdraft());
		System.out.println();
		check.withdraw(18000);
		System.out.println("您的账户余额为:"+check.getBalance());
		System.out.println("您的可透支额为:"+check.getOverdraft());
		System.out.println();
		check.withdraw(3000);
		System.out.println("您的账户余额为:"+check.getBalance());
		System.out.println("您的可透支额为:"+check.getOverdraft());
	}
}

4、在下面的代码结构中:使用关键字:this,super;方法的重写;继承;

package com.atguigu.exer1;


/*
 * 圆
 */
public class Circle {
	private double radius;//半径
	
	public Circle() {
		radius = 1.0;
	}

	public double getRadius() {
		return radius;
	}

	public void setRadius(double radius) {
		this.radius = radius;
	}
	//返回圆的面积
	public double findArea() {
		
		return Math.PI*radius*radius;
		
	}
	
}
package com.atguigu.exer1;

/*
 * 圆柱
 */
public class Cylinder extends Circle{
	private double length;//高

	public Cylinder() {
		length=1.0;
	}

	public double getLength() {
		return length;
	}

	public void setLength(double length) {
		this.length = length;
	}
	//返回圆柱的体积
	public double findeArea() {//重写
		
		return super.findArea()*length;
		//return Math.PI*getRadius()*getRadius()*length;
	
	}
	//返回圆的表面积
	public double findeVolume() {
		
		return super.findArea()*2+Math.PI*2*getRadius()*length;
		//return Math.PI*getRadius()*getRadius()*2+Math.PI*2*getRadius()*length;
	}
	
	
	
}
package com.atguigu.exer1;

public class CylinderTest {
	public static void main(String[] args) {
		//实例化对象
		Cylinder cylinder = new Cylinder();
		cylinder.setRadius(2.1);//半径
		cylinder.setLength(13.2);//高
		
		double value = cylinder.findArea();
		System.out.println("圆柱的体积:"+value);//圆柱的体积:13.854423602330987
		
		double area = cylinder.findeVolume();
		System.out.println("圆的表面积:"+area);//圆的表面积:201.8787439196801
		
		
	}
}

5.面向对象特征之三:多态性

5.1多态性举例:AnimalTest类,Cat类,Dog类

package com.atguigu.java4;

import java.sql.Connection;

/*
 * 多态性的使用举例一:
 */
public class AnimalTest {
	public static void main(String[] args) {
		AnimalTest test = new AnimalTest();
		test.func(new Dog());
		
		
		test.func(new Cat());
	}
	
	
	public void func(Animal animal) {//Animal animal = new Dog();
		animal.eat();
		animal.shout();
		if(animal instanceof Dog) {
			Dog d = (Dog)animal;
			d.watchDoor();
		}
	}
	
	//多态性省略了以下方法,只用一个func(Animal animal)都可以调用
//	public void func(Dog dog) {//只能new Dof();的对象
//		dog.eat();
//		dog.shout();
//	}
//	public void func(Cat cat) {
//		cat.eat();
//		cat.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("汪!汪!汪!");
	}
	public void watchDoor() {
		System.out.println("看门");
	}
}

class Cat extends Animal{
	public void eat() {
		System.out.println("猫吃鱼");
	}
	public void shout() {
		System.out.println("喵!喵!喵!");
	}
}


/*
 * 举例二:
 */

class Order{
	public void method(Object obj) {
		
	}
}

/*
 * 举例三:MySQL/Oracle传那个对象就能调用那个对象的对应的方法,
 */
class Driver{
	public void doDate(Connection conn) {//conn = new MySQLConnection()/new OracleConnection();
		//规范的步骤去操作数据
//		conn.method();
//		conn.method();
//		conn.method();
	}
}





5.2练习:基本操作:子类继承父类


  1.若子类重写了父类方法,就意味着子类里定义的方法彻底覆盖了父类里的 同名方法,
     系统将不可能把父类里的方法转移到子类中。:编译看左边,运行看右边。

  2.对于实例变量则不存在这样的现象,即使子类里定义了与父类完全相同的实例变量,
     这个实例变量依然不可能覆盖父类中定义的实例变量:编译运行都看左边

package com.atguigu.exer;
/*
 * 练习:子类继承父类
 * 1.若子类重写了父类方法,就意味着子类里定义的方法彻底覆盖了父类里的 同名方法,
 * 	系统将不可能把父类里的方法转移到子类中。:编译看左边,运行看右边。
 * 
 * 2.对于实例变量则不存在这样的现象,即使子类里定义了与父类完全相同的实例变量,
 * 	这个实例变量依然不可能覆盖父类中定义的实例变量:编译运行都看左边
 * 
 * 
 * 
 */
class Base {
	int count = 10;
	
	public void display() {
		System.out.println(this.count);
	}
}

class Sub extends Base {
	int count = 20;
	
	public void display() {
		System.out.println(this.count);
	}
}
/*
 * 开发中不要定义相同的属性
 */
public class FieldMethodTest {
	public static void main(String[] args){
		
		Sub s = new Sub();
		System.out.println(s.count);//20
		
		s.display();//20
		Base b = s;//多态性:Base b = new Sub();
		//==,对于引用数据类型来讲,比较的是两个引用数据变量的地址值是否相同
		System.out.println(b == s);//true
		System.out.println(b.count);//10,多态性:属性,编译运行都看左边
		b.display();//20,多态性:方法,编译看左边,运行看右边。
	}
}

 5.3.基本操作:建立InstanceTest 类,在类中定义方法method(Person e);

              

package com.atguigu.exer;
/*
 *				建立InstanceTest 类,在类中定义方法
 *				method(Person e);
 *				在method中:
 *				(1)根据e的类型调用相应类的getInfo()方法。
 *				(2)根据e的类型执行:
 *					如果e为Person类的对象,输出:
 *					“a person”;
 *					如果e为Student类的对象,输出:
 *					“a student”
 *					“a person ” 
 *					如果e为Graduate类的对象,输出:
 *					“a graduated student”
 *					“a student”
 *					“a person” 
 * 
 * 
 */

public class InstanceTest {
	public static void main(String[] args) {
		InstanceTest test = new InstanceTest();
		
		test.method(new Person());
		System.out.println("***********");
		test.method(new Student());
		System.out.println("***********");
		test.method(new Graduate());
		
		
	}
	public void method(Person e) {
		
		//虚拟方法调用
		String info = e.getInfo();
		System.out.println(info);
		
		//方式一:
//		if(e instanceof Graduate) {
//			System.out.println("a graduated student");
//			System.out.println("a  student");
//			System.out.println("a Person");
//		}else if(e instanceof Student) {
//			System.out.println("a  student");
//			System.out.println("a Person");
//		}else {
//			System.out.println("a Person");
//		}
		//方式二:子类--->父类:Graduate--->Student--->Person
		//如果a instanceof A返回true,则a instanceof B也会返回true
		//其中,类B是类A的父类。
		if(e instanceof Graduate) {
			System.out.println("a graduated student");
		}
		if(e instanceof Student) {
			System.out.println("a  student");
		}
		if(e instanceof Person) {
			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;
	 }
 }

5.4几何图形

定义三个类,父类 GeometricObject 代表几何形状,子类 Circle 代表圆形, MyRectangle 代表矩形。
定义一个测试类 GeometricTest
编写 equalsArea 方法测试两个对象的面积是否相等(注意方法的参 数类型,利用动态绑定术),编写displayGeometricObject 方法显示对象的面积(注意方法的参 数类型,利用动态绑定技术)。

 父类GeometricObject:

package com.atguigu.exer;
/*
 * 几何图形
 */
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) {
		this.weight = weight;
	}
	/*
	 * 获取面积
	 */
	public double findArea() {
		return 0.0;
	}
}
子类 Circle代表圆形:
package com.atguigu.exer;
/*
 * 圆形
 */
public class Circle extends GeometricObject {
	private double radius;//半径
	
//	public Circle() {
//		
//	}
	public Circle(double radius,String color,double weight) {
		super(color,weight);
		this.radius = radius;
	}
	public double getRadius() {
		return radius;
	}
	public void setRadius(double radius) {
		this.radius = radius;
	}
	//计算圆形面积
	public double findArea() {
		return Math.PI*radius*radius;
	}
	
}

MyRectangle代表矩形:

package com.atguigu.exer;
/*
 * 矩形
 */
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;
	}
}
定义一个测试类 GeometricTest:
package com.atguigu.exer;
/*
 * 定义一个测试类GeometricTest,
 * 编写equalsArea方法测试两个对象的面积是否相等(注意方法的参数类型,利用动态绑定技术),
 * 编写displayGeometricObject方法显示对象的面积(注意方法的参数类型,利用动态绑定技术)。
 */
public class GeometricTest {
	public static void main(String[] args) {
		GeometricTest test = new GeometricTest();
//		test.displayGeometricObject(new Circle(2.0, "黑", 3.2));
//		test.displayGeometricObject(new MyRectangle(3.2, 2.0, "白", 3) );
//		
//		test.equalsArea(new Circle(2.0, "黑", 3.2), new MyRectangle(3.2, 2.0, "白", 3));
		Circle c1 = new Circle(2.0, "黑", 3.2);
		test.displayGeometricObject(c1);
		Circle c2 = new Circle(2.0, "黑", 3.2);
		boolean isEquals = test.equalsArea(c1, c2);
		System.out.println("c1和c2面积是否相等:"+isEquals);
		
		MyRectangle m1 = new MyRectangle(3.2, 2.0, "白", 3);
		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 area) {
		System.out.println("面积为:"+area.findArea()); 
	}
}

6.多态是编译时行为还是运行时行为? 如何证明?

举例一:使用随机数来演示:

package com.atguigu.java5;

import java.util.Random;

//面试题:多态是编译时行为还是运行时行为?
//证明如下:
class Animal  {
 
	protected void eat() {
		System.out.println("animal eat food");
	}
}

class Cat  extends Animal  {
 
	protected void eat() {
		System.out.println("cat eat fish");
	}
}

class Dog  extends Animal  {
 
	public void eat() {
		System.out.println("Dog eat bone");

	}

}

class Sheep  extends Animal  {
 

	public void eat() {
		System.out.println("Sheep eat grass");

	}

 
}

public class InterviewTest {

	public static Animal  getInstance(int key) {
		switch (key) {
		case 0:
			return new Cat ();
		case 1:
			return new Dog ();
		default:
			return new Sheep ();
		}

	}

	public static void main(String[] args) {
		int key = new Random().nextInt(3);

		System.out.println(key);

		Animal  animal = getInstance(key);
		
		animal.eat();
		 
	}

}

举例二:重写与重载

package com.atguigu.exer;
//考查多态的笔试题目:
public class InterviewTest1 {

	public static void main(String[] args) {
		Base1 base = new Sub1();
		base.add(1, 2, 3);//此为重写

		Sub1 s = (Sub1)base;//向下转型,可以调用子类独有的方法
		s.add(1,2,3);//重载
	}
}

class Base1 {
	public void add(int a, int... arr) {//"......"可变形参
		System.out.println("base1");
	}
}

class Sub1 extends Base1 {

	public void add(int a, int[] arr) {//可变形参
		System.out.println("sub_1");
	}

	public void add(int a, int b, int c) {//当调用的参数是3个时,优先使用当前方法
		System.out.println("sub_2");
	}

}

7.Object类:equals()

7.1编写Order类,重写父类的equals()方法:并判断测试类中创建的两个对象是否相等

编写 Order 类,
int 型的 orderId String 型的 orderName
相应的getter()和 setter() 方法,两个参数的构造器,
重写父类的 equals() 方法: public boolean equals(Object obj),
并判断测试类中创建的两个对象是否相等
package com.atguigu.exer2;
/*
 * 编写Order类,
 * 有int型的orderId,String型的orderName,
 * 相应的getter()和setter()方法,两个参数的构造器,
 * 重写父类的equals()方法:public boolean equals(Object obj),
 * 并判断测试类中创建的两个对象是否相等。
 */
public class Order {
	public static void main(String[] args) {
		Order order1 = new Order(1001, "Tom");
		Order order2 = new Order(1001, "Jerry");
		System.out.println("两个对象是否相同:"+order1.equals(order2));//false
		
		Order order3 = new Order(1001, "Jerry");
		System.out.println("两个对象是否相同:"+order3.equals(order2));//true
		
		//当重写的equals()-->this.orderName.equals(order.orderName)时://true
		//当重写的equals()-->this.orderName == order.orderName时://false
		//new String("Jerry")不能使用"=="来进行比较
		Order order4 = new Order(1001, new String("Jerry"));
		System.out.println("order3与order4是否相同:"+order3.equals(order4));
		
		
		
		
//		String s1 = "BB";
//		String s2 = "BB";
//		//变量s1、s2存在栈中,但是常量值"BB"却不再堆中,而在方法区里,为什么两者相等呢?
//		//原因:常量值有个特点,当定义的变量的常量值与已有的相重了,那么会直接被复用,两个变量指向同一个地址。
//		System.out.println(s1 == s2);//true
		
	}
	private int orderId;
	private String orderName;
	public Order(int orderId, String orderName) {
		super();
		this.orderId = orderId;
		this.orderName = orderName;
	}
	public int getOrderId() {
		return orderId;
	}
	public void setOrderId(int orderId) {
		this.orderId = orderId;
	}
	public String getOrderName() {
		return orderName;
	}
	public void setOrderName(String orderName) {
		this.orderName = orderName;
	}
	
	@Override
		public boolean equals(Object obj) {
		if(this == obj) {
			return true;
		}
		if(obj instanceof Order) {
			Order order = (Order)obj;
			//比较两个属性是否相同
//			if(this.orderName == order.orderName && this.orderId == order.orderId) {
//					return true;
//			}else {
//				return false;
//			}
//或;orderName:为string类型,可以使用equals(),并且对比的是两个对象的“实体内容”是否相同
/* 当属性为基本数据类型时,用==比较。如果出现引用数据类型时:要用equals(),进行比较,== 
   不能用.==只能比较如"Tom"一样实参对象的地址值,但如果对象输入的实参“new 
   String("Jarry")” 时就无法比较了,返回值只有false;
*/
			//正确:
		return this.orderId == order.orderId && this.orderName.equals(order.orderName);
			//错误:
		//return this.orderId == order.orderId && this.orderName == order.orderName;
		}else {
		    return false;
		}
	}
		
}

}

7.2请根据以下代码自行定义能满足需要的MyDate类:equals()重写

请根据以下代码自行定义能满足需要的MyDate类,
 在MyDate类中覆盖equals方法,
 使其判断当两个MyDate类型对象的年月日都相同时,结果为true,否则为false。
 public boolean equals(Object o)

public class EqualsTest {
        public static void main(String[] args ) {
                MyDate m1 = new MyDate(14, 3, 1976);
                MyDate m2 = new MyDate(14, 3, 1976);
                if ( m1 == m2 ) {
                        System. out .println( "m1==m2" );
                } else {
                        System. out .println( "m1!=m2" ); // m1 != m2
                }
                if ( m1 .equals( m2 )) {
                        System. out .println( "m1 is equal to m2" ); // m1 is equal to m2
                } else {
                        System. out .println( "m1 is not equal to m2" );
                }
        }
}
package com.atguigu.exer2;
/*
 * 请根据以下代码自行定义能满足需要的MyDate类,
 * 在MyDate类中覆盖equals方法,
 * 使其判断当两个MyDate类型对象的年月日都相同时,结果为true,否则为false。
 *  public boolean equals(Object o)
 */
public class MyDateTest {
	public static void main(String[] args) {
		
		MyDate m1 = new MyDate(14, 3, 1976);
		MyDate m2 = new MyDate(14, 3, 1976);
		
		if (m1 == m2) {
			System.out.println("m1==m2");
		} else {
			System.out.println("m1!=m2"); // m1 != m2
			}
		if (m1.equals(m2)) {
			System.out.println("m1 is equal to m2");// m1 is equal to m2
		} else {
			System.out.println("m1 is not equal to m2");
			}
	}
}

class MyDate{
	private int day;
	private int month;
	private int year;
	public MyDate(int day, int month, int year) {
		super();
		this.day = day;
		this.month = month;
		this.year = year;
	}
	public int getDay() {
		return day;
	}
	public void setDay(int day) {
		this.day = day;
	}
	public int getMonth() {
		return month;
	}
	public void setMonth(int month) {
		this.month = month;
	}
	public int getYear() {
		return year;
	}
	public void setYear(int year) {
		this.year = year;
	}
	@Override
	public boolean equals(Object o) {
		if(this == o) {
			return true;
		}
		if(o instanceof MyDate) {
			MyDate date = (MyDate)o;
			return this.day == date.day && this.month == date.month && this.year == date.year;
		}
		return false;
	}
	
}

8、Object类,toString()方法

8.1、面试题:下列输出结果是多少?数组int,char,double,String;toString()在类的对象中使用

--像String、Date、File、包装类等都重写了Object类中的toString()方法
 ·使得在调用对象的toString()方法时,返回“实体内容”信息;正常的类,返回值为类的地址值

--println()方法,除了char类型数组,打印的为实体内容。其他类型打印的都是地址值或null 

package com.atguigu.exer3;

public class Test9 {
	public static void main(String[] args) {
		Test9 test = new Test9();
		test.test();
		
	}
	public void test() {
		char[] arr = new char[] { 'a', 'b', 'c' };
		System.out.println(arr);//abc
		System.out.println(arr.toString());//[C@15db9742
		int[] arr1 = new int[] { 1, 2, 3 };
		System.out.println(arr1);//[I@15db9742
		double[] arr2 = new double[] { 1.1, 2.2, 3.3 };
		System.out.println(arr2);//[D@6d06d69c
		
		String[] arr3 = new String[] {"CC","AA","BB"};
		System.out.println(arr3);//[Ljava.lang.String;@4e25154f
//-------------------------------------------------------------------------------
        Customer cust1 = new Customer("Tom",21);
		System.out.println(cust1.toString());//com.atguigu.java1.Customer@15db9742
		System.out.println(cust1);//com.atguigu.java1.Customer@15db9742

        String str = new String("MM");
		System.out.println(str);//MM
		System.out.println(str.toString());//MM
		
		Date date = new Date(45615671L);
		System.out.println(date.toString());//Thu Jan 01 20:40:15 CST 1970
		System.out.println(date);//Thu Jan 01 20:40:15 CST 1970

        
		}
}

9、Object类:重写toString(),equals()方法。几何图形问题

·定义两个类:

---父类GeometricObject代表几何形状,

---子类Circle代表圆形。

·写一个测试类:

---创建两个Circle对象,

---判断其颜色是否相等;

---利用equals方法判断其半径是否相等;

---利用 toString()方法输出其半径。

 父类GeometricObject代表几何形状,

package com.atguigu.exer3;
/*
 * 定义两个类,父类GeometricObject代表几何形状,子类Circle代表圆形。
 */
public class GeometricObject {
	
	protected String color;//颜色
	protected double weight;//权重
	
	public GeometricObject() {
		super();
		this.color = "white";
		this.weight = 1.0;
	}

	public GeometricObject(String color, double weight) {
		super();
		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;
	}
	
	
	
}

子类Circle代表圆形: 

package com.atguigu.exer3;

public class Circle extends GeometricObject {
	
	private double radius;//半径

	public Circle() {
		super();//在构造器中已经进行了初始化
		radius = 1.0;
//		color = "white";
//		weight = 1.0;
	}

	public Circle(double radius) {
		super();
		this.radius = radius;
	}
	
	public Circle(double radius,String color,double weight) {
		super(color,weight);
		this.radius = radius;
		
	}
	public double getRadius() {
		return radius;
	}

	public void setRadius(double radius) {
		this.radius = radius;
	}
	
	//计算圆的面积
	public double findArea() {
		return Math.PI*radius*radius;
	}
	
	//重写equals()方法
	//比较个圆的半径是否相等,如相等,返回true。
	@Override
	public boolean equals(Object obj) {
		if(this == obj) {
			return true;
		}
		if(obj instanceof Circle) {
			Circle c = (Circle)obj;
			return this.radius == c.radius;
			//return this.color.equals(c.color);
		}
		
		
		return false;
	}
	//重写toString()方法,用于输出半径长度
	@Override
	public String toString() {
		
		return "Circle[radius ="+this.radius+"]";
	}
	
	
	
}

写一个测试类:

---创建两个Circle对象,

---判断其颜色是否相等;

---利用equals方法判断其半径是否相等;

---利用 toString()方法输出其半径。

package com.atguigu.exer3;
/*
 * 写一个测试类,创建两个Circle对象,
 * 判断其颜色是否相等;
 * 利用equals方法判断其半径是否相等;
 * 利用toString()方法输出其半径。
 */
public class CircleTest {
	public static void main(String[] args) {
		Circle circle1 = new Circle(2.0, "white", 1.0);
		Circle circle2 = new Circle(1.0, "white", 2.0);
		//判断颜色是否相等
		System.out.println("颜色是否相等:"+circle1.getColor().equals(circle2.getColor()));
//		if(circle1.color.equals(circle2.color)) {
//			System.out.println("两个圆的颜色相同");
//		}else{
//			System.out.println("两个圆的颜色不相同");
//		}
//		
		//半径是否相等
		System.out.println("半径是否相等:"+circle1.equals(circle2));
//		boolean isFalg = circle1.equals(circle2);
//		System.out.println("c1和c2的半径是否相等:"+isFalg);
		
		System.out.println("半径长为:"+circle2);
		System.out.println("半径长为:"+circle1.toString());
	}
}

10. 包装类(Wrapper)的使用:利用Vector代替数组处理:从键盘读入学生成绩(以负数代表输入结束),找出最高分,并输出学生成绩等级。

利用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等
  
  
  Vector:已有的工具类:java.util.Vector;----->就像Scanner类一样

个人练习:

package com.atguigu.exer4;

import java.util.Scanner;
import java.util.Vector;

/*
 * 利用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等
 * 
 * 
 * Vector:已有的工具类
 * 
 */
public class ScoreTest {
    public static void main(String[] args) {
		//1.实例化Scanner,用于从键盘获取学生成绩
    	Scanner scan = new Scanner(System.in);
    	
    	//2.创建Vector对象,Vector v=new Vector();相当于原来的数组
    	Vector v=new Vector();
    	//3.通过for(;;)或while(true)方式,为Vector中添加数组
    	double score;
    	
    	while(true) {
    		
    		System.out.println("请输入学生成绩:");
    		 score = scan.nextDouble();
    		 
    		 //3.1添加操作:v.addElement(Object obj);
    		 if(score >=0) {
    			 //Double sc = new Double(score);
    			 v.addElement(score);//装箱
    			
    		 }else {//3.2当输入是负数时,就跳出循环
    			 break;
    		 }
    	}
    	
    	//计算向量的长度:v.size()
    	System.out.println("向量Vector的长度:"+v.size());
    	//4.获取学生成绩的最大值
    	double max = 0;
    	for(int j=0;j < v.size();j++) {
    		Object obj = v.elementAt(j);
    		Double sc = (Double)obj;
    		score = sc;
    		if(score >= max) {
    			max = score;
    		}
    	}
    	System.out.println("成绩最大值为:"+max);
    	
    	//5.遍历Vector,得到每个学生的成绩,并与最大成绩比较,得到每个学生的等级
    	for(int j=0;j < v.size();j++) {
    		Object obj=v.elementAt(j);
    		score = (Double)obj;//拆箱
    		
    		int value = (int)(max - score);//计算与最大值的差值
    		char level;//等级
    		switch(value/10) {
    		case 0:
    			level = 'A';
    			break;
    		case 1:
    			if(value == 10) {
    				level = 'A';
    				break;
    			}
    			level = 'B';
    			
    			break;
    		case 2:
    			if(value == 20) {
    				level = 'B';
    				break;
    			}
    			level = 'C';
    			break;
    		default:
    			if(value == 30) {
    				level = 'C';
    				break;
    			}
    			level = 'D';
    			break;
    		}
    		System.out.println("student-"+" "+j+" "+"score is"+" "+score+" "+",level is"+" "+level);
    	}
    	
	}
}

}

答案:

package com.atguigu.exer4;

import java.util.Scanner;
import java.util.Vector;

/*
 * 利用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等
 * 
 * 
 * Vector:已有的工具类
 */
public class ScoreTest1 {
	public static void main(String[] args) {
		//1.实例化Scanner,用于从键盘获取学生成绩
		Scanner scan = new Scanner(System.in);
		
		//2.创建Vector对象,Vector v=new Vector();相当于原来的数组
		Vector v=new Vector();
		
		//3.通过for(;;)或while(true)方式,为Vector中添加数组
		int maxScore = 0;//最大值
		for(;;) {
			System.out.println("请输入学生成绩(以负数代表输入结束):");
			int score  = scan.nextInt();
			
			//3.2当输入是负数时,就跳出循环
			if(score <0) {
				break;
			}
			if(score >100) {
				System.out.println("输入的数据非法,请重新输入");
				continue;
			}
			//3.1添加操作:v.addElement(Object obj);
//			//JDK5.0之前:
//			Integer inScore = new Integer(score);
//			v.addElement(inScore);//多态
			
			//JDK5.0之后
			v.addElement(score);//自动装箱
			
			//4.获取学生成绩的最大值
			
			if(maxScore < score) {
				maxScore = score;
			}
			
		}
		System.out.println("学生成绩最大值maxScore为:"+maxScore);
		
		
		//5.遍历Vector,得到每个学生的成绩,并与最大成绩比较,得到每个学生的等级
		char level;
		for(int i=0;i<v.size();i++) {
			Object obj = v.elementAt(i);
//			//在JDK5.0之前
//			Integer inScore = (Integer)obj;
//			int score = inScore.intValue();
			//JDK5.0之后
			int score = (int)obj;//自动拆箱
			
			if(maxScore - score <= 10) {
				level = 'A';
			}else if(maxScore - score <= 20) {
				level = 'B';
			}else if(maxScore - score <= 30) {
				level = 'C';
			}else {
				level = 'D';
			}
			System.out.println("student-"+" "+i+" "+"score is"+" "+score+" "+",level is"+" "+level);
		}
		
	}
}

Python 面向对象编程 (OOP) 练习题通常会涉及到以下几个核心概念: 1. **和对象**:创建一个,如`Person`,包含属性(如`name`和`age`)和方法(如`__init__`初始化函数和`say_hello`打招呼方法)。实例化这个会产生一个对象。 ```python class Person: def __init__(self, name, age): self.name = name self.age = age person1 = Person("Alice", 25) ``` 2. **继承**:通过`extends`关键字创建子,如`Student`继承自`Person`,添加额外属性如`school`和方法如`study`. ```python class Student(Person): def __init__(self, name, age, school): super().__init__(name, age) self.school = school student1 = Student("Bob", 20, "MIT") ``` 3. **封装**:用`private`(以双下划线开头)或`protected`(仅限于子访问)修饰属性,控制其可见性。 4. **多态**:演示方法重写和方法覆盖,例如`parent_class`有一个`display()`方法,子可以有自己的实现版本。 5. **抽象和接口**:使用`abc`模块定义接口,创建抽象,确保某些方法必须实现。 6. **魔术方法**(特殊方法):如`__str__`、`__len__`等,用于提供特定行为。 7. **工厂和工厂方法**:设计模式的应用,用来创建复杂对象或控制对象的创建过程。 练习题可能会让你实现这些特性,并解决实际问题,比如管理学生信息、创建动态游戏角色等。完成这些题目有助于巩固对Python OOP的理解。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值