0726(017天 接口&内部类)

0726(017天 接口&内部类)

每日一狗(田园犬西瓜瓜

在这里插入图片描述

接口&内部类

1. 接口(i打头)

一种无法统一到一个类中,但是有又同一种功能是我们所需要研究的。我们这里需要定义一个规则,定义具体的实现类中必须实现的一些方法,而一个具体的类需要的方法可能来自多个规则中,此时抽象类就无法满足我们的多继承需求了,但是java中允许接口的多实现。

在Java中不直接支持多继承,因为会出现调用的不确定性,所以Java将多继承机制进行改良,在Java中 变成了多实现。一个类可以实现多个接口,一个接口可以继承多个接口。

1.1 一些细节

  • 接口是一种特殊的抽象类,接口只能被abstract或者public修饰
  • 接口没有构造器方法
  • 没有属性,只能定义常量
  • 可以包含抽象方法,也可以没有抽象方法
  • 声明 访问修饰符 interface 接口名{ } 一般建议接口名称使用形容词
    • 外部的接口只能使用public、默认这两个范围限定词;如果定义内部接口则可以使用4大范围限定 词
    • 如果定义public接口,则规则和定义public类一致,要求接口名称和文件名称一致

1.2 能定义啥

  • 公共常量:

    • public finaly static String name = “lanou”;
    • 声明同时直接赋值,不允许后续赋值
  • 抽象方法:公共

    • public abstract void pp();
  • 默认方法:JDK1.8以后允许默认方法

    • public default void pp(){//代码体}
    • 有具体实现的代码块
  • 静态方法:JDK1.8中允许在接口中定义静态方法

    • public static void pp(){静态代码体}
    • 只能通过接口自身进行直接调用,不能通过实现类对象进行调用,实现类也不能调用。
    • 静态方法可以被默认方法调用
  • 私有方法(jdk9开始包括9)

    • private
    • 接口之外不可访问,只能在接口范围内进行调用

1.3 实现类

  • class 类名称 implements 接口1, 接口2… { }

  • 接口中允许多重继承,类可以实现多个接口。一个接口可以被多个子类实现。一个子类还可以实现多个接口

  • 接口方法重复时,必须对其中冲突的方法进行重写。

interface IA4 {
	public default void pp() {
		System.out.println("IA4...pp");
	}
}

interface IB4 {
	public default void pp() {
		System.out.println("IB4...pp");
	}
}

public class A4 implements IA4, IB4 {
	@Override
	public void pp() {
		IA4.super.pp();
		System.out.println("A4...pp");
		IB4.super.pp();
	}
}
  • 不能完全实现接口的所有的抽象方法的必须声明为抽象类
interface IA5 {
	void pp1();
	void pp2();
}

abstract class A5 implements IA5 {
	public void pp2() {
		System.out.println("A5...pp");
	}
}
  • 接口的抽象方法默认都是public的,在实现接口时必须用public关键字在方法头上说明
interface IA2 {
	void pp();
}
class B2 implements IA2 {
	public void pp() {}
}

1.4 接口的特殊特征

  • 一个类只能有一个父类!
  • 一个类可以实现多个接口!
  • 一个接口可以继承多个接口
  • 一个类也可以在继承一个类的同是实现多个接口!
interface 接口名 extends 接口名称1 ,父接口名称2 , ... { }
class 类名 implements 接口1, 接口2... { }

1.5 接口的作用

  • 统一访问
接口 obj=new 实现1(); 可以还有实现2,实现3等
obj只能调用接口中定义的方法
  • 解耦 通过接口可以隔离具体实现

    解耦就是 在使用者 和 实现者 之间没有关系。 无论实现者如何改变实现,对于使用者使用不会变化

1.6 接口和抽象类的异同点(考点)

  • 相同点:都是不断向上抽取而来的

  • 不同点:

    • 抽象类需要被继承,而且只能单继承
    • 接口需要被实现,而且可以多实现
  • 抽象类中可以定义抽象方法和非抽象方法,子类继承后可以直接使用非抽象方法

  • 接口中可以定义抽象方法和default方法,抽象方法必须由子类去提供实现;JDK1.8+ 中允许接口中 的方法有默认实现,实现类中可以直接使用默认实现,允许覆盖定义

  • 逻辑关系不同:

    • 抽象类的继承是is a关系,在定义该体系的基本共性内容
    • 接口的实现是like a关系,在定义体系额外功能
  • 属性的支持

    • 接口中只能定义常量,而且必须被初始化,
    • 抽象类中可以定义属性,允许在声明时直接初始化,也可以不初始化,同时允许定义常量
  • 方法的定义

    • 接口中的公共方法应该全部是抽象的,JDK1.8+版本中可以通过default关键字定义方法的默认实现,允 许定义静态方法,JDK1.9开始可以定义私有方法;
    • 抽象类中可以有抽象方法也可以有普通方法

1.7 如何使用接口

接口中定义调用规范,抽象类实现接口,提供公共功能,最终具体实现类实现特殊的方法。

方法的传参和返回值类型尽可能用抽象的或接口,可以少些很多逻辑代码,在调用不同。

一般使用接口隔离具体实现,可以将类之间的相互依赖变为类对接口的依赖。例如出差类和会飞的东西 是通过会飞的接口进行隔离,这样不管出差类需要修改或者会飞的东西需要修改,都不会相互影响

如果一组相关的类中有公共的方法和特殊的方法,可以使用抽象类,在抽象类中固化公共的方法【算法 骨架】,而无需具体子类重复实现;但是在抽象类中无法实现的方法可以延迟到子类中再实现。例如排 序器BubbleSorter,其中抽象类BubbleSorter固化了所使用的冒泡排序算法,而将无法实现的bigger比 较算法延迟到BubbleSorter的子类PigSorter中实现,同时PigSorter中也不需要重新定义排序算法

最佳软件开发实践:先定义接口规范调用方法,在使用抽象类实现接口定义公共方法,最后再定义具体 子类实现所有的方法

1.8 接口和抽象类的使用场景

从设计层面看,抽象类体现继承关系is a,它主要描述类的从属关系或者父子关系,抽象类和它的派生类 之间是典型的IS-A关系,即子is a父。

interface可以多实现,而且不要求实现者和interface定义在概念本质上是一致的,仅仅是实现了 interface定义的契约而已。它主要描述的是类型间的行为合同,接口和它的实现类之间是典型的CANDO关系,即子can do父。

为什么接口需要默认方法?

在接口添加默认方法不需要修改实现类,接口新增的默认方法在实现类中直接可用。

另外还要注意默认方法冲突问题。(需要在实现类中重写并做具体的说明)


2. 面向对象设计的6大原则

这会不讲(待补充)


3. 内部类

将一个类定义置入另一个类定义中,这就叫作“内部类”

3.1 定义

命名规则:内部类不允许和当前外部类名重名(字节码文件:外部类名$内部类名.class)

class A1{
    public class B1{
        
    }
}
  • 内部类的范围限定词可以使用四种不同的范围限定词
  • 外部类只能用 公共的 和 默认
  • 内部类可以访问外部类的所有成员方法
  • 非静态内部类不能拥有静态成员
  • 静态内部类只能访问外部类的静态成员

3.2 作用

  • 内部类提供更好的封装
  • 内部类可以直接访问外部类的私有成员
  • 外部类不能直接访问内部类的成员,需要构建内部类对象才能访问
  • 匿名内部类适合用于创建仅仅使用一次使用的类

应用条件:

  • 分析事物是发现该事物描述还有事物,而且这个事物还在访问被描述事物的内容,两个东西同生共死(例如:牛和牛的腿)
  • 一个事物离开了另一个事物就没有存在的价值。
  • 内部类能直接访问外部

3.3 内部类的分类

成员内部类

非静态内部类

  • 不允许声明静态成员属性,可以定义静态常量,可以机场分类的静态成员
  • 类范围修饰符无要求

静态内部类

  • 无中生有,可以不用先new外部类,直接new内部类

  • 只能使用外部类的静态成员

局部内部类

  • 在类的方法中定义的类
  • 不能定义静态方法属性,除非是继承的或常量
  • 局部内部类中可以使用所在方法的局部常量。(内部类会人为它会填一个 final )

匿名内部类

没有名字的内部类/内部类的简写格式

一般来说会配合一个父类或接口的方式来使用

两种写法,匿名及简写

没有构造器

一般情况下,当一个类只用一次,其他地方不会在使用,就是使用这个。

3.4 内部类的使用场景和好处

  • 每个内部类都能独立的继承一个接口的实现,所以无论外部类是否已经继承了某个(接口的)实现, 对于内部类都没有影响。内部类使得多继承的解决方案变得完整
  • 方便将存在一定逻辑关系的类组织在一起,又可以对外界隐藏
public class{
	private class 牛腿{}
}

  • 方便编写事件驱动程序
btn.addActionListener(new ActionListener() { //添加按钮对应的事件处理
    public void actionPerformed(ActionEvent e) {
		showNewWindow(mainWin);
    }
});

  • 方便编写线程代码。

扩展小芝士

  • 密封包(限制其他类的继承)
    • 方案一:使用final,不允许被继承。如那些三个字符串类型,八种基本数据类型
    • 方案二:使用默认范围限定词,只能在当前包中继承
    • 方案三:密封包(17才有的)
public sealed class MyClass permits B1, B2,B3{} // 需要指定子类

// 三种继承式
public final class  B1 extend MyClass{} // 没孩子了

public not-sealed class B2 extends MyClass{} // 释放密封特性

public sealed class B3 extends MyClass permits C1{} // 继承了密封包特性, 需要指定自己的子类

练习题

第1题考核知识点:属性与多态无关

package com.lianxiti;

public class Test01 {

	public static void main(String[] args) {
		A a = new B();
		System.out.println(a.num); // 1
		System.out.println(((B) a).num); // 2
		System.out.println(((A) ((B) a)).num); // 1
		System.out.println("-------------------");
		B b = new B();
		System.out.println(b.num); // 2
		System.out.println(((A) b).num); // 1
		System.out.println(((B) ((A) b)).num); // 2
	}
}

class A {
	int num = 1;
}

class B extends A {
	int num = 2;
}

第2题考核知识点:实例初始化方法,属性与多态无关

package com.lianxiti;

public class Test02 {
	public static void main(String[] args) {
		Father f = new Son();
		System.out.println(f.x);
		/*
		 * 先调用父类的构造方法 this.print(); 这个方法子类是有的 Son.x = 0 子类这里是没有x黑为初始化及默认值 修改父类的 x = 20
		 * 
		 * 在调用子类的构造方法 this.print();Son.x = 30
		 * 
		 * 输出f.x = 20
		 * 
		 */
	}
}

class Father {
	int x = 10;

	public Father() {
		this.print();
		x = 20;
	}

	public void print() {
		System.out.println("Father.x = " + x);
	}
}

class Son extends Father {
	int x = 30;

	public Son() {
		this.print();
		x = 40;
	}

	public void print() {
		System.out.println("Son.x = " + x);
	}
}

第3题考核知识点:多态,重写,实例初始化过程

package com.lianxiti;

public class Test03 {
	public static void main(String[] args) {
		Base b1 = new Base();
		Base b2 = new Sub();
		/*
		 * base : 100
		 * 
		 * sub : 100 // 方法会向子找
		 * 
		 * sub : 70
		 */

	}
}

class Base {
	Base() {
		method(100);
	}

	public void method(int i) {
		System.out.println("base : " + i);
	}
}

class Sub extends Base {
	Sub() {
		super.method(70);
	}

	public void method(int j) {
		System.out.println("sub : " + j);
	}
}

第4题考核知识点:多态、重载、重写

package com.lianxiti;

public class Test04 {
	public static void main(String[] args) {
		A4 a1 = new A4();
		A4 a2 = new B4();
		B4 b = new B4();
		C4 c = new C4();
		D4 d = new D4();
		/*
		 * B继承与A,C、D继承B
		 * 
		 * B中有 A、B、D
		 * 
		 * A中有 A、D
		 */
		System.out.println("(1)" + a1.show(b)); // A and A
		System.out.println("(2)" + a2.show(d)); // A and D
		System.out.println("(3)" + b.show(c)); // B and B
		System.out.println("(4)" + b.show(d)); // A and D
	}
}

class B4 extends A4 {
	public String show(B4 obj) {
		return "B and B";
	}

	public String show(A4 obj) {
		return "B and A";
	}
}

class A4 {
	public String show(D4 obj) {
		return ("A and D");
	}

	public String show(A4 obj) {
		return "A and A";
	}
}

class C4 extends B4 {
}

class D4 extends B4 {
}

第5题考核知识点:多态、重载、重写

特殊,匹配时在声明类中去找,执行时拿着匹配好的去实际对象中找

在这里插入图片描述

package com.lianxiti;

public class Test05 {
	public static void main(String[] args) {
		/*
		 * B继承与A,C、D继承B
		 * 
		 * B中有 B、A、C
		 * 
		 * A中有 A、C
		 * 
		 */
		A5 a1 = new A5();
		A5 a2 = new B5();
		B5 b = new B5();
		C5 c = new C5();
		D5 d = new D5();
		System.out.println("(1)" + a1.show(b)); // A and A
		System.out.println("(2)" + a2.show(d)); // A and C  改 B and A // 最优匹配时在声明类中匹配,执行时在实际类中调用方法
		System.out.println("(3)" + b.show(c)); // A and C
		System.out.println("(4)" + b.show(d)); // B and B

	}
}

class A5 {
	public String show(C5 obj) {
		return ("A and C");
	}

	public String show(A5 obj) {
		return "A and A";
	}
}

class B5 extends A5 {
	public String show(B5 obj) {
		return "B and B";
	}

	public String show(A5 obj) {
		return "B and A";
	}
}

class C5 extends B5 {
}

class D5 extends B5 {
}

第6题考核知识点:属性与多态无关

package com.lianxiti;

public class Test06 {
	public static void main(String[] args) {
		/*
		 * 属性向父类中找
		 */
		Base1 b = new Sub1();
		System.out.println(b.x); // 1
	}
}

class Base1 {
	int x = 1;
}

class Sub1 extends Base1 {
	int x = 2;
}

第7题考核知识点:权限修饰符

如下代码是否可以编译通过,如果能,结果是什么,如果不能,为什么?

不能,两个公共类,且私有成员不能被访问

package com.lianxiti;

public class Test07 extends Father1 {
	public String grade;

	public static void main(String[] args) {
		Father1 f = new Test07();
//		System.out.println(f.name); // 私有成员不能被继承
	}
}

class Father1 {
	private String name = "lanou";
	int age = 0;
}

第8题考核知识点:继承,super,static

如下代码是否可以编译通过,如果能,结果是什么,如果不能,为什么?

  • 构造方法的第一行才能写 this() 或 super()

  • 静态方法中无法调用改对象的非静态属性

public class Person {
	public Person() {
		System.out.println("this is a Person.");
	}
}

public class Teacher extends Person {
	private String name = "tom";

	public Teacher() {
		System.out.println("this is a teacher.");
//        super();  // 构造函数调用必须是构造函数中的第一条语句
	}

	public static void main(String[] args) {
		Teacher tea = new Teacher();
//        System.out.println(this.name); // 不能在静态上下文中使用它
	}
}

第9题

知识点:抽象类 语法点:继承,抽象类 按步骤编写代码,效果如图所示:

在这里插入图片描述

编写步骤:

1 定义抽象类A,抽象类B继承A,普通类C继承B

2 A类中,定义成员变量numa,赋值为10,抽象showA方法。

3 B类中,定义成员变量numb,赋值为20,抽象showB方法。

4 C类中,定义成员变量numc,赋值为30,重写showA方法,打印numa,重写showB方法,打印 numb,定义showC方法,打印numc。

5 测试类Test09中,创建C对象,调用showA方法,showB方法,showC方法。

第10题

知识点:抽象类

案例:

1、声明抽象父类Person,包含抽象方法public abstract void pee();

2、声明子类Woman,重写抽象方法,打印坐着尿

3、声明子类Man,重写抽象方法,打印站着上尿

4、声明测试类Test10,创建Person数组,存放Woman和Man对象,并遍历数组,调用pee()方法

package com.lianxiti.T10;

public abstract class Person {
	public abstract void pee();
}
//===========================
package com.lianxiti.T10;

public class Woman extends Person {

	@Override
	public void pee() {
		System.out.println("坐着尿");

	}

}

//===========================
package com.lianxiti.T10;

public class Man extends Person {

	@Override
	public void pee() {
		System.out.println("站着尿");
	}

}

//===========================
package com.lianxiti.T10;

public class Man extends Person {

	@Override
	public void pee() {
		System.out.println("站着尿");
	}

}


//===========================
package com.lianxiti.T10;

public class Test10 {

	public static void main(String[] args) {
		Person[] pArr = new Person[3];
		pArr[0] = new Woman();
		pArr[1] = new Man();
		pArr[2] = new Man();
		/*
		 * 坐着尿 站着尿 站着尿
		 */
		for (Person i : pArr) {
			if (i instanceof Woman) {
				Woman tmp = (Woman) i;
				tmp.pee();
			}
			if (i instanceof Man) {
				Man tmp = (Man) i;
				tmp.pee();
			}
		}
	}

}

第11题

知识点:抽象类

案例:

1、声明抽象父类Person,包含抽象方法public abstract void eat();

2、声明子类中国人Chinese,重写抽象方法,打印用筷子吃饭

3、声明子类美国人American,重写抽象方法,打印用刀叉吃饭

4、声明子类印度人Indian,重写抽象方法,打印用手抓饭

5、声明测试类Test11,创建Person数组,存储各国人对象,并遍历数组,调用eat()方法

package com.lianxiti.T11;

public abstract class Person {
	public abstract void eat();
}

//==============================
package com.lianxiti.T11;

public class American extends Person {

	@Override
	public void eat() {
		System.out.println("用刀叉吃饭");
	}

}

//==============================
package com.lianxiti.T11;

public class Chinese extends Person {

	@Override
	public void eat() {
		System.out.println("用筷子跌饭");
	}

}

//==============================
package com.lianxiti.T11;

public class Indian extends Person {

	@Override
	public void eat() {
		System.out.println("手抓饭");
	}

}

//==============================
package com.lianxiti.T11;

public class Test11 {

	public static void main(String[] args) {
		Person[] pArr = new Person[3];
		pArr[0] = new Chinese();
		pArr[1] = new American();
		pArr[2] = new Indian();
		/*
		 * 用筷子跌饭 用刀叉吃饭 手抓饭
		 * 
		 */
		for (Person i : pArr) {
			if (i instanceof Chinese) {
				Chinese c = (Chinese) i;
				c.eat();
			} else if (i instanceof American) {
				American a = (American) i;
				a.eat();
			} else if (i instanceof Indian) {
				Indian in = (Indian) i;
				in.eat();
			}

		}
	}

}


第13题

案例:

1、在com.yan.test13包中声明员工类、程序员类、设计师类、架构师类

员工类属性:编号、姓名、年龄、薪资

程序员类属性:编程语言,默认都是"java"

设计师类属性:奖金

架构师类属性:持有股票数量

要求:属性私有化,无参有参构造,get/set,getInfo方法(考虑重写)

2、在com.yan.test13包中声明Test13测试类

(1)在main中有一些常量和一个二维数组

(2)创建一个员工数组

(3)根据以上数据,初始化员工数组 提示:把字符串转为int和double类型的值,可以使用如下方式:

(4)遍历数组,使用如下格式

//==============================
package com.lianxiti.test13;

public class Employee { // 员工类
	private String ID;
	private String name;
	private String age;
	private String salary; // 薪水

	@Override
	public String toString() {
		return "Staff [ID=" + ID + ", name=" + name + ", age=" + age + ", salary=" + salary + "]";
	}

	public String getInfo() {
		return "员工编号 =" + ID + ", 姓名 =" + name + ", 年龄=" + age + ", 薪资 =" + salary;
	}

	// ================

	public Employee(String iD, String name, String age, String salary) {
		super();
		ID = iD;
		this.name = name;
		this.age = age;
		this.salary = salary;
	}

	public Employee() {
	}

	public String getID() {
		return ID;
	}

	public void setID(String iD) {
		ID = iD;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getAge() {
		return age;
	}

	public void setAge(String age) {
		this.age = age;
	}

	public String getSalary() {
		return salary;
	}

	public void setSalary(String salary) {
		this.salary = salary;
	}

}

//==================================================================================
package com.lianxiti.test13;

public class Programmer extends Employee { // 程序员
	private String language; // 编程语言

	public Programmer() {
		language = "Java";
	}

	public Programmer(String iD, String name, String age, String salary) {
		super(iD, name, age, salary);
		this.language = "Java";
	}

	public String getInfo() {
		return super.getInfo() + "编程语言 =" + language;
	}
	// ===========

	public String getLanguage() {
		return language;
	}

	public void setLanguage(String language) {
		this.language = language;
	}
}

//==================================================================================
package com.lianxiti.test13;

public class Designer extends Programmer { // 设计师
	private String bonus;

	public String getInfo() {
		return super.getInfo() + "奖金 =" + bonus;
	}

	public Designer() {
	}

	public Designer(String iD, String name, String age, String salary, String bonus) {
		super(iD, name, age, salary);
		this.bonus = bonus;
	}

	// ============================
	public String getBonus() {
		return bonus;
	}

	public void setBonus(String bonus) {
		this.bonus = bonus;
	}

}

//==================================================================================
package com.lianxiti.test13;

public class Architect extends Designer { // 架构师
	private String stock;

	public Architect() {
	}

	public Architect(String iD, String name, String age, String salary, String bonus, String stock) {
		super(iD, name, age, salary, bonus);
		this.stock = stock;
	}

	public String getInfo() {
		return super.getInfo() + " 持股数 =" + stock;
	}
	// ==================

	public String getStock() {
		return stock;
	}

	public void setStock(String stock) {
		this.stock = stock;
	}

}

//==================================================================================
package com.lianxiti.test13;

public class Test13 {
//员工编号 =1, 姓名 =段誉, 年龄=22, 薪资 =3000
//员工编号 =2, 姓名 =令狐冲, 年龄=32, 薪资 =18000编程语言 =Java奖金 =15000
//员工编号 =3, 姓名 =任我行, 年龄=23, 薪资 =7000编程语言 =Java
//员工编号 =4, 姓名 =张三丰, 年龄=24, 薪资 =7300编程语言 =Java
//员工编号 =5, 姓名 =周芷若, 年龄=28, 薪资 =10000编程语言 =Java奖金 =5000
//员工编号 =6, 姓名 =赵敏, 年龄=22, 薪资 =6800编程语言 =Java
//员工编号 =7, 姓名 =张无忌, 年龄=29, 薪资 =10800编程语言 =Java奖金 =5200
//员工编号 =8, 姓名 =韦小宝, 年龄=30, 薪资 =19800编程语言 =Java奖金 =15000
//员工编号 =9, 姓名 =杨过, 年龄=26, 薪资 =9800编程语言 =Java奖金 =5500
//员工编号 =10, 姓名 =小龙女, 年龄=21, 薪资 =6600编程语言 =Java
//员工编号 =11, 姓名 =郭靖, 年龄=25, 薪资 =7100编程语言 =Java
//员工编号 =12, 姓名 =黄蓉, 年龄=27, 薪资 =9600编程语言 =Java奖金 =4800

	public static void main(String[] args) {
		final int EMPLOYEE = 10;
		final int PROGRAMMER = 11;
		final int DESIGNER = 13;
		final int ARCHITECT = 14;
		String[][] EMPLOYEES = { { "10", "1", "段誉", "22", "3000" },
				{ "13", "2", "令狐冲", "32", "18000", "15000", "2000" }, { "11", "3", "任我行", "23", "7000" },
				{ "11", "4", "张三丰", "24", "7300" }, { "12", "5", "周芷若", "28", "10000", "5000" },
				{ "11", "6", "赵敏", "22", "6800" }, { "12", "7", "张无忌", "29", "10800", "5200" },
				{ "13", "8", "韦小宝", "30", "19800", "15000", "2500" }, { "12", "9", "杨过", "26", "9800", "5500" },
				{ "11", "10", "小龙女", "21", "6600" }, { "11", "11", "郭靖", "25", "7100" },
				{ "12", "12", "黄蓉", "27", "9600", "4800" } };

		Employee[] eArrs = new Employee[EMPLOYEES.length];
		int i = 0;
		String ID, name, age, salary, bonus, stock;
		for (String[] ss : EMPLOYEES) {
			int leiBie = Integer.parseInt(ss[0]);
			switch (leiBie) {
			case EMPLOYEE:
				ID = ss[1];
				name = ss[2];
				age = ss[3];
				salary = ss[4];
				eArrs[i++] = new Employee(ID, name, age, salary);
				break;
			case PROGRAMMER:
				ID = ss[1];
				name = ss[2];
				age = ss[3];
				salary = ss[4];
				eArrs[i++] = new Programmer(ID, name, age, salary);
				break;
			case ARCHITECT:
				ID = ss[1];
				name = ss[2];
				age = ss[3];
				salary = ss[4];
				bonus = ss[5];
				stock = ss[6];
				eArrs[i++] = new Architect(ID, name, age, salary, bonus, stock);
				break;
			default:
				ID = ss[1];
				name = ss[2];
				age = ss[3];
				salary = ss[4];
				bonus = ss[5];
				eArrs[i++] = new Designer(ID, name, age, salary, bonus);
				break;
			}
		}
		for (Employee e : eArrs) {
			System.out.println(e.getInfo());
		}
	}

}

第14题

案例:

1、在com.yan.test14包中声明图形Graphic、圆Circle、矩形Rectangle类、三角形Triangle类

2、图形Graphic类中有:

①public double getArea()方法:返回面积

②public double getPerimeter()方法:返回周长

③public String getInfo()方法:返回图形信息

3、圆类和矩形类重写这两个方法

4、在com.yan.test14包中声明测试类Test14_1

(1)请设计一个方法,可以用于比较两个图形的面积是否相等

(2)请设计一个方法,可以用于找出两个图形中面积大的那个

(3)public static void main(String[] args){} 在主方法中,创建1个圆、1个矩形、1个三角形对象,并分别调用(1)、(2)方法进行测试。

5、在com.yan.test14包中测试类Test14_2

(1)请设计一个方法,可以用于遍历一个图形数组

(2)请设计一个方法,可以用于给一个图形数组进行按照面积从小到大排序

(3)public static void main(String[] args){} 在主方法中,创建1个圆、1个矩形、1个三角形对象,放到数组中,遍历显示,然后排序后再遍历显 示。

//=================================图形类========================================
package com.lianxiti.test14;

public abstract class Graphic {
	private int sideNums;

	public abstract Double getArea();

	public abstract double getPerimeter();

	public abstract String getInfo();

	public int getSideNums() {
		return sideNums;
	}

	public void setSideNums(int sideNums) {
		this.sideNums = sideNums;
	}
}

//==============================圆===============================================
package com.lianxiti.test14;

public class Circle extends Graphic {
	private static final double PI = 3.14;
	private double R;

	public Circle() {
		R = 1;
		setSideNums(Integer.MAX_VALUE);
	}

	public Circle(double R) {
		this();
		this.R = R;
	}

	@Override
	public Double getArea() {
		return R * R * PI;
	}

	@Override
	public double getPerimeter() {
		return 2 * PI * R;
	}

	@Override
	public String getInfo() {

		return "图形: 圆形; 半径=" + R;
	}

}

//==============================矩形============================================
package com.lianxiti.test14;

public class Rectangle extends Graphic {
	private double a;
	private double b;

	public Rectangle() {
		setSideNums(4);
		a = 1;
		b = 1;
	}

	public Rectangle(double a, double b) {
		setSideNums(4);
		this.a = a;
		this.b = b;
	}

	@Override
	public Double getArea() {
		return a * b;
	}

	@Override
	public double getPerimeter() {
		return 2 * (a + b);
	}

	@Override
	public String getInfo() {
		return "形状: 矩形; 边长: " + a + "和" + b;
	}

}

//==============================三角形========================================
package com.lianxiti.test14;

public class Triangle extends Graphic {
	private int a, b, c;

	public Triangle() {
		a = 3;
		b = 4;
		c = 5;
	}

	public Triangle(int a, int b, int c) {
		this();
		if (a + b > c && b + c > a && a + c > b) {
			this.a = a;
			this.b = b;
			this.c = c;
		}
	}

	@Override
	public Double getArea() {
		double p = (a + b + c) / 2.0;

		return Math.sqrt(p * (p - a) * (p - b) * (p - c));
	}

	@Override
	public double getPerimeter() {

		return a + b + c;
	}

	@Override
	public String getInfo() {

		return "形状:三角形 三条边: " + a + ", " + b + ", " + c + ",";
	}

}

//=================================测试类==========================================
package com.lianxiti.test14;

import java.util.Random;

/*
图形: 圆形; 半径=9.0面积=254.34
图形: 圆形; 半径=8.0面积=200.96
形状: 矩形; 边长: 11.0和9.0面积=99.0
图形: 圆形; 半径=5.0面积=78.5
形状:三角形 三条边: 9, 15, 16,面积=66.332495807108
形状:三角形 三条边: 15, 13, 10,面积=64.06246951218786
形状: 矩形; 边长: 4.0和14.0面积=56.0
形状:三角形 三条边: 12, 6, 13,面积=35.894811602792956
形状: 矩形; 边长: 9.0和1.0面积=9.0
图形: 圆形; 半径=1.0面积=3.14
 */
public class Test {
	static Random r = new Random();

	public static void main(String[] args) {
		Graphic[] gArrs = new Graphic[10];

		for (int i = 0; i < gArrs.length; i++) {
			switch (r.nextInt(3)) {
			case 0:
				gArrs[i] = getTriangle();
				break;
			case 1:
				gArrs[i] = getCircle();
				break;
			default:
				gArrs[i] = Rectangle();
				break;
			}
		}
		areaSort(gArrs);
		for (Graphic g : gArrs) {
			System.out.println(g.getInfo() + "面积=" + g.getArea());
		}

	}

	public static void areaSort(Graphic[] arrs) {
		for (int i = 1; i < arrs.length; i++) {
			for (int j = 0; j < arrs.length - i; j++) {
				if (!areaLarge(arrs[j], arrs[j + 1])) {
					Graphic tmp = arrs[j];
					arrs[j] = arrs[j + 1];
					arrs[j + 1] = tmp;
				}
			}
		}
	}

	// 面积是否相等
	public static boolean areaEquals(Graphic g1, Graphic g2) {
		return Math.abs(g1.getArea() - g2.getArea()) <= 0.001;
	}

	// 判定 g1 > g2
	public static boolean areaLarge(Graphic g1, Graphic g2) {
		return g1.getArea() > g2.getArea();
	}

	// 生成三角形对象
	public static Triangle getTriangle() {
		int a, b, c;
		while (true) {

			a = r.nextInt(20) + 1;
			b = r.nextInt(20) + 1;
			c = r.nextInt(20) + 1;
			if (a + b > c && a + c > b && b + c > a) {
				break;
			}
		}
		return new Triangle(a, b, c);
	}

	// 生成圆形对象
	public static Circle getCircle() {
		double R = r.nextInt(10) + 1;
		return new Circle(R);
	}

	// 生成矩形对象
	public static Rectangle Rectangle() {
		int a, b;
		a = r.nextInt(20) + 1;
		b = r.nextInt(20) + 1;
		return new Rectangle(a, b);
	}
}

第15题(代做)

案例:

1、在com.yan.test15包中声明人Person、男人Man、女人Woman类

(1)在Person类中,包含 ①public void eat():打印吃饭 ②public void toilet():打印上洗手间

(2)在Man类中,包含 ①重写上面的方法 ②增加 public void smoke():打印抽烟

(3)在Woman类中,包含 编号 姓名 年龄 薪资 语言 奖金 股票 … 1 2 ①重写上面的方法 ②增加 public void makeup():打印化妆

2、在com.yan.test15包中声明测试类Test15

(1)public static void meeting(Person… ps) 在该方法中,每一个人先吃饭,然后上洗手间,然后如果是男人,随后抽根烟,如果是女人,随后 化个妆

(2)public static void main(String[] args) 在主方法中,创建多个男人和女人对象,并调用meeting()方法进行测

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值