201521123063 《Java程序设计》 第4周学习总结

1.本周学习总结

1.1 尝试使用思维导图总结有关继承的知识点。

1.2 使用常规方法总结其他上课内容。

  • 类设计
    一般在设计类的时候,要考虑这些类是否有共性,还要考虑其独特性,使共同的父类拥有这些共性,可以减少麻烦,可以用个构造函数或初始化块对属性初始化

  • 注释:
    文档化注释一般写在类定义前或函数定义前且这种格式注释支持javadoc生成HTML格式的帮助文档(这个没要求就不细写了)

    (1)//             (只能注释单行)
    (2)/* ···  */  (可注释多行)
    (3)/**
         *
         */           (文档化注释)
  • 继承和多态
    继承时子类获得父类的方法和属性,能够实现代码的复用,减少代码冗余,但是父类不能用子类的方法和属性,子类可以保存特性这,子类可以覆盖父类的方法
    注意:(1)如果子类的一个方法名和父类的相同,但是new一个子类对象,想调用父类的方法可以使用super关键字进行调用,而且必须是子类构造函数第一个执行的句
    (2)父类无参的构造函数会比子类先执行
    (3)一个类只能有一个直接的父类,但是可多层次继承,object默认是所有类的父类

  • 抽象类
    (1)抽象类不能被实例化,否则会报错,只有抽象类的非抽象子类才可以创建对象

    (2)抽象类必须被继承,方法必须被子类重写,但是构造方法和类方法不能声明为抽象方法
    (3)当多个类有相同功能或成员变量时,一般使用抽象类,来减少代码量,会更加方便

  • 访问修饰符允许范围
    private:本类(作用范围最小)
    默认:本类、同包
    protected:本类、同包、子类
    public本类、同包、子类、其他均可

  • final关键字
    (1)父类方法中被final修饰的,在子类中是不允许被重写的
    (2)如果用final修饰类,则它就不允许被继承,比如String类,以下为内部源代码

public final class String
    implements java.io.Serializable, Comparable<String>, CharSequence {
    /** The value is used for character storage. */
    private final char value[];

    /** Cache the hash code for the string */
    private int hash; // Default to 0

    /** use serialVersionUID from JDK 1.0.2 for interoperability */
    private static final long serialVersionUID = -6849794470754667710L;

(3)如果修饰的是对象,则对象里的属性和方法使可以更改的,只是引用不能改变

  • instanceof用法
    当左边声明的类型与右边是同种类或有继承关系时返回true,即左边是右边的实例
    如果存在关系 Apple extends Fruit,Fruit extends Food
    if(sth instanceof Fruit)
    当sth是Apple的一个对象,则返回true
    当sth是Fruit的一个对象,则返回true
    当sth是Food的一个对象,则返回false
  • 强制类型转换
    向上转换:子类可以很自认转为父类
    向下转换:父类强制转换为子类时只有当引用类型真正的身份为子类时才会强制转换成功,否则失败
  已知:Manager extends Employee();
  Employee staff1 = new Employee();
  Manager boss1=(Manager)staff1; //会报错!
  Employee staff2 = new Manager();
  Manager boss2=(Manager)staff2;//编译通过

2. 书面作业

1.注释的应用

使用类的注释与方法的注释为前面编写的类与方法进行注释,并在Eclipse中查看。(截图)
如下:

2面向对象设计(大作业1,非常重要)

2.1 将在网上商城购物或者在班级博客进行学习这一过程,描述成一个故事。(不得少于50字,参考QQ群中PPT的范例)
以网上商城购物为例:
登录:需要输入账号密码,还要通过验证码,如下所示,感觉很厉害,就跟12306的验证码一样需要鼠标点击

比如我想要看三毛的书,输入关键字,经过查找,找到一系列他写的书,发现有分纸质书和电子书,我选择《稻草人手记》直接加入购物车,在购物车中还能选择数量,还能收藏商品,删除商品,点击结算后,跳出需要输入收货地址,收件人,联系方式的界面,但是发现会默认保存上次购物的地址,直接确认或修改地址就完成了

2.2 通过这个故事我们能发现谁在用这个系统,系统中包含的类及其属性方法,类与类之间的关系。尝试找到这些类与属性,并使用思维导图描述类、属性、方法及类与类之间的关系。
分析:这个故事当然是我在用这个系统了...系统中包含的类,属性和方法:
(1)订单(Order):包含订单号,订单条目,要支付的总金额,收货信息
(2)订单条目(Item):包含商品,商品数量,
(3)商品(Product):包含商品名,类别,单价,ISBN编码,还有根据销售量进行排名后的名次等
(4)购物车(Car):包含:商品,数量,还有收藏、增加、删除商品、结算的功能
(5)收货信息(Address):包含收件人、联系电话、具体地址
(6)账户(Account):包含用户名、登录密码、输入验证码
思维导图:

2.3 尝试使用Java代码实现故事中描述的这一过程(不必很完善),将来要在这个基础上逐渐完善、扩展成一个完整的面向对象的系统。(可选:加分)
一下是部分代码

商品类:
package Shopping;

public class Product {
	private String name;
	private double price;
	private String kind;
	private String ISBN;
	private Iterm iterm;
	private int count;
}
订单类:
public class Order {
	private Iterm i;
	private Address ad;
	private double money;
	private String address;
	private String numbers;
}
地址类:
public class Address {
	private String name;
	private String phone;
	private String detail;
	
}
购物车类
public class Car {
    private Order o;
    
	public static void Aad() {
		
	}

    public static void Cut() {
		
	}
    public static Product Aadgoods(Product p) {
    	//...
    	return p;
		
	}
    public static Product Cutgoods(Product p) {
		//...
		return p;
	}
    public static double Calculatemoney(Product p) {
    	int sum=0;
    	//...
		return sum;
	}
}

UML类图(很丑...我也没办法)

3.ManagerTest.zip代码分析

分析ManagerTest.zip中的代码,回答几个问题:
3.1 在本例中哪里体现了使用继承实现代码复用?回答时要具体到哪个方法、哪个属性。

public Manager(String n, double s, int year, int month, int day)
   {
      super(n, s, year, month, day);
      bonus = 0;
   }

这个Manager类当中的构造方法用了父类的构造方法,实现代码的复用

Manage类中:
 public double getSalary()
   {
      double baseSalary = super.getSalary();
      return baseSalary + bonus;
   }
使用super继承了父类Employee中getSalary方法
public double getSalary()
   {
      return salary;
   }

3.2 Employee类及其子类Manager都有getSalary方法,那怎么区分这两个方法呢?

答:区分的话可以用super来调用父类的,如果直接创建子类对象,不使用super的话,就默认使用子类的getSalary方法

3.3 文件第26行e.getSalary(),到底是调用Manager类的getSalary方法还是Employee类的getSalary方法。

答:26行内容:System.out.println("name=" + e.getName() + ",salary=" + e.getSalary());
 应该要看e所表示的类型,第一个用的是Manager的(Manager的getSalary方法是先调用了父类的),第二个和第三个都是Employee的,在两个类的方法中加了语句之后:

3.4 Manager类的构造函数使用super调用父类的构造函数实现了代码复用,你觉得这样的有什么好处?为什么不把父类构造函数中的相关代码复制粘贴到Manager的构造函数中,这样看起来不是更直观吗?

答:好处在于不需要再写相同的代码,直接复制粘贴会产生代码冗余,感觉没什么必要

4.Object类

4.1 编写一个Fruit类及属性String name,如没有extends自任何类。使用System.out.println(new Fruit());是调用Fruit的什么方法呢?该方法的代码是从哪来的?尝试分析这些代码实现了什么功能?
答:运行结果:Fourthwork.Fruit@15db9742,实际上就是调用了Fruit的toString方法,这个方法没有显示地表示出来,如果生成toString方法,
则运行结果就变成:Fruit[name=null]
如下为源代码:

4.2 如果为Fruit类添加了toString()方法,那么使用System.out.println(new Fruit());调用了新增的toString方法。那么其父类中的toString方法的代码就没有了吗?如果同时想要复用其父类的toString方法,要怎么操作?(使用代码演示)

答:可以用super来调用
public class Fruit {
	String name;

	@Override
	public String toString() {
		return "Fruit [name=" + name + "]" + super.toString();
	}

	public static void main(String[] args) {

		System.out.println(new Fruit());
	}
}
运行结果:Fruit [name=null]Fruit@15db9742

4.3 Fruit类还继承了Object类的eqauls方法。尝试分析其功能?自己编写一个equals方法覆盖父类的相应方法,功能为当两个Fruit对象name相同时(忽略大小写),那么返回true。(使用代码证明你自己覆盖的eqauls方法是正确的

最初的equals方法
	public boolean equals(Object obj) {
		if (this == obj)      //比较两个对象是否是指向同一个
			return true;
		if (obj == null)      //如果是空的就不相同了
			return false;
		if (getClass() != obj.getClass())
			return false;
		Fruit other = (Fruit) obj;//开始比较属性等是否一样...
		if (name == null) {
			if (other.name != null)
			    return false;
		} else if (!name.equals(other.name))
			return false;
		return true;
	}
覆盖的equals方法:
public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Fruit other = (Fruit) obj;
		if (name == null) {
			if (other.name != null)
				return false;
		} else if (!name.equalsIgnoreCase(other.name))
			return false;
		return true;
}
main函数:
public static void main(String[] args) {
        Fruit a=new Fruit("banana");
        Fruit b=new Fruit("BANANA");
        Fruit c=new Fruit("banananana");
        System.out.println(a.name+" "+b.name+" "+a.equals(b));
        System.out.println(a.name+" "+c.name+" "+a.equals(c));
}
运行结果:
banana BANANA true
banana banananana false

4.4 在4.3的基础上使用ArrayList<Fruit> fruitList存储多个fruit,要求如果fruitList中已有的fruit就不再添加,没有的就添加进去。请编写相关测试代码。并分析ArrayList的contatins方法是如何实现其功能的?

public static void main(String[] args) {
		ArrayList<Fruit> list=new ArrayList<Fruit>();
		Scanner scan=new Scanner(System.in);		
		while(scan.hasNext()){
			String s=scan.nextLine();
			if(s.equals("end"))
				break;
			Fruit f=new Fruit(s);
			if(!list.contains(f)){
				list.add(f);
			}
		}
		System.out.println(list.toString());
		scan.close();
}
运行结果;
apple
apple
banana
orange
end
[Fruit [name=apple], Fruit [name=banana], Fruit [name=orange]]

contains方法的源代码:

public boolean contains(Object o) {
        return indexOf(o) >= 0;    //找到对象则返回true
    }

public int indexOf(Object o) {
        if (o == null) {
            for (int i = 0; i < size; i++)
                if (elementData[i]==null)// elementData:存储向量组件的数组缓冲区,vector 的容量就是此数据缓冲区的长度
                    return i;            // 最后一个元素后的任何数组元素都为 null
        } else {
            for (int i = 0; i < size; i++)
                if (o.equals(elementData[i]))
                    return i;            //如果匹配返回下标
        }
        return -1;                       //没找到返回负数
    }

5.代码阅读:PersonTest.java(abstract、多态)

5.1 画出类的继承关系
原先用Xmind画的不大好,最后直接用UML生成更方便

5.2 读懂main函数,将自己推测的出代码运行结果与真正运行结果进行比较。尝试分析原因

运行结果:
Manager [bonus=12000.3, toString()=Employee [salary=90000.1, toString()=Person [name=Clark, adress=GE, phonenumber=111, email=111@mail.com, age=10, gender=mail]]]
Student [status=1, toString()=Person [name=wang, adress=110, phonenumber=15959, email=15959@163.com, age=18, gender=male]]
Employee [salary=1000.0, toString()=Person [name=zhang, adress=136, phonenumber=1360, email=1360@mail.com, age=21, gender=female]]
Programmer [allowance=50000.0, toString()=Employee [salary=100000.0, toString()=Person [name=Gates, adress=usa, phonenumber=911, email=911@com, age=59, gender=male]]]

分析:因为Person是一个抽象类,包含子类的共同属性和方法,但是具体的方法要看子类的执行,在main函数里已经实例化成Person的子类对象,或继承的分支对象就拿最后一个输出来分析:因为Programmer extends Employee,Employee extends Person,在Programmer有参构造函数里先执行父类 Employee的有参构造函数而 Employee又会先执行Person的构造函数,才会有如上的输出结果

5.3 子类中里面使用了super构造函数,作用是什么?如果将子类中的super构造函数去掉,行不行?

答:作用可以减少代码量,有现成的就用,如果把Programmer构造函数的super那一行注释掉,会报错,注释掉之后一般会调用父类无参的构造函数,但这时候并没有这个函数
    会提醒要显式调用另一个

5.4 PersonTest.java中的代码哪里体现了多态?你觉得多态有什么好处?多态和继承有什么关系吗?

答:每个类中都有toString方法,但是它们返回的内容都不一样,即同一个行为具有多个不同表现形式
    多态好处:可扩充,可替换,简单灵活
    要实现多态的前提是要有继承或者实现关系,当中要有方法的重写,要有父类引用指向子类对象,所以二者密切相关

3.码云代码提交记录

  • 在码云的项目中,依次选择“统计-Commits历史-设置时间段”, 然后搜索并截图

4.PTA实验

题目集:jmu-Java-03-面向对象1-基础-封装继承 中的
函数(4-1, 4-2, 4-3,4-4较难选做)
编程(5-4, 5-5, 5-6)
一定要有实验总结

  • 4-1
    这题比较简单,直接用super关键字调用父类的toString方法,再加上company.toString()进行复写toString方法即可

  • 4-2
    这题就是根据输入的类型来创建对象,先存放在对象数组中,最后逆序输出(即自动输出toString方法)

  • 4-3
    (1)使用了java.text.DecimalFormat;如下为API文档解释:

    DecimalFormat df = new DecimalFormat("#.##");
    df.format(a)
    这两句就是为了让a保留两位小数的意思,不足两位,用0补上
    (2)重写了equals方法,先判断当前对象是否是指向同一个,接着判断是否为空指向,最后再判断内容是否一致

  • 5-4
    在上周的5-3实验中,Rectangle类、Circle类中都写了各自的计算周长和面积的方法,最后再Main类里逐一使用,显得比较繁琐,这题就用到了抽象类,通过继承的关系来实现代码的复用,Shape类中集中了子类共同的方法,通过输入判断类型再创建对象就能很好解决计算全部周长和面积的问题

  • 5-5
    这题关键在于要考虑创建的对象是否已经存在,可以用ArrayList的contains方法,在上面题目中已经介绍过了,但是由于一开始不清楚这个方法,我先覆盖了equals方法,利用循环来加以判断是否需要添加到对象数组中,如果最后用System.out.println(Arrays.toString(PersonOverride.class.getConstructors()));输出就完成了

  • 5-6
    这一题说实话很烦...至今还没搞完...可能对那些方法的运用不够熟练,比如ArrayList...

原文地址:https://www.cnblogs.com/lyq063/p/6562190.html