这几天逐渐被idea所折服,越来越喜欢这个优雅又强大的代码编辑器,有很多人说idea对很多初学者不友好,但是在我看来,只要你足够自律,并且英语不会太差,语法上关键的几个单词没什么大问题,idea对初学者是有很大帮助的。因为idea强大的语法检查功能对初学者十分友好,idea提供各种错误提示,以及各个需要注意的地方,这让初学者可以轻松找到出错的代码块。好了,下面来看题目吧!
狗生活在陆地上(是一种陆生动物),既是哺乳类的也是肉食性的。
狗通常的时候和人打招呼会通过“摇摇尾巴”,在被抚摸情绪很好的时候,
会“旺旺叫”,而在受到惊吓情绪烦躁时,会发出“呜呜”声;
猫也生活在陆地上(是一种陆生动物),既是哺乳类的也是肉食性的。
猫通常的时候和人打招呼会发出“喵~”的声音,在被抚摸情绪很好时,
会发出“咕噜咕噜”声,而在受到惊吓时,会发出“嘶嘶”声;
青蛙是一种两栖动物(既是水生动物也是陆生动物),既不是哺乳类的也不是肉食性的,
属于卵生。青蛙通常的时候和人打招呼会通过“呱呱叫”,当青蛙情绪好的时候,
会在岸边“呱呱呱”的唱歌,而在受到惊吓时,会“扑通一声跳入水中”
//下面只实现了狗的模块,猫和青蛙模块同理,不再赘述
//因为水生和陆生不能抽象处出来共性,因此将其定义为接口
package com.company;
abstract class Animal
{
static final int HAPPY = 1;
static final int UNHAPPY = 0;
protected boolean carnivorous; //肉食
protected boolean mammal; //哺乳
public abstract void sayHello();
public abstract void sayHello(int mood);
public boolean isCarnivorous()
{
return carnivorous;
}
public boolean isMammal()
{
return mammal;
}
}
//水生动物
interface Water
{
boolean hasGillFlag(); //是否有腮
}
//陆生动物
interface Land
{
int getLegNumber(); //有多少条腿
}
class Dog extends Animal implements Land
{
private int dogLegNumber = 4;
//访问父类的属性
//父类使用权限protected
Dog()
{
this.carnivorous = true;
this.mammal = true;
}
public void sayHello()
{
System.out.println("摇摇尾巴");
}
public void sayHello(int mood)
{
switch (mood)
{
case HAPPY:
System.out.println("汪汪叫");
break;
case UNHAPPY:
System.out.println("呜呜叫");
break;
default:
System.out.println("摇摇尾巴");
}
}
public int getLegNumber()
{
return dogLegNumber;
}
}
public class TaskDay09_4 {
public static void main(String[] args)
{
Dog dog = new Dog();
if(dog.mammal)
System.out.println("狗是哺乳动物");
else
System.out.println("狗不是哺乳动物");
if(dog.carnivorous)
System.out.println("狗是肉食动物");
else
System.out.println("狗不是肉食性动物");
System.out.print("狗通常的打招呼方式是:" );
dog.sayHello();
System.out.print("狗开心的时候的打招呼方式是:" );
dog.sayHello(Animal.HAPPY);
System.out.print("狗不开心的时候的打招呼方式是:" );
dog.sayHello(Animal.UNHAPPY);
System.out.println("狗是肉食动物,狗有" + dog.getLegNumber() + "条腿");
}
}
总结:这道题因为水生和陆生不能抽象处出来共性,因此需要将其定义为接口
package com.company;
interface Usb
{
String getDeviceInfo();
}
class Mouse implements Usb
{
public String getDeviceInfo()
{
return "鼠标";
}
}
class KeyBoard implements Usb
{
public String getDeviceInfo()
{
return "键盘";
}
}
class Upan implements Usb
{
public String getDeviceInfo()
{
return "U盘";
}
}
class Computer
{
private Usb usb1;
private Usb usb2;
private Usb usb3;
public Computer(){}
public Computer(Usb usb1, Usb usb2, Usb usb3)
{
this.usb1 = usb1;
this.usb2 = usb2;
this.usb3 = usb3;
}
public void showInfo()
{
System.out.println(usb1.getDeviceInfo());
System.out.println(usb2.getDeviceInfo());
System.out.println(usb3.getDeviceInfo());
}
}
public class TaskDay09_1 {
public static void main(String[] args)
{
Usb usb1 = new Mouse();
Usb usb2 = new KeyBoard();
Usb usb3 = new Upan();
Computer com = new Computer(usb1, usb2, usb3);
com.showInfo();
}
}
总结:在做这道题的时候面向对象的思想不明确,导致题意不懂。
只需要将USB定义为接口,接口的作用是用来展示键盘、鼠标、U盘各个设备的信息。键盘、鼠标、U盘只需要分别定义为一个类实现接口即可。将电脑定义为一个类,其中包含了三个USB对象,并通过方法试实现展示功能。
注意:接口是抽象的,不能用来实例化对象,只能通过实现接口的各个类和实例化对象。因此在main函数中利用多态来实现函数功能。
汽车作为交通工具的一种,实现了驾驶的方法(在马路上驾驶)
火车作为交通工具的一种,实现了驾驶的方法(在铁路上驾驶)
飞机作为交通工具的一种,实现了驾驶的方法(在天上驾驶)
需求:做一个测试类,在测试类的main函数中,分别实例化一个汽车的对象,火车的对象和飞机的对象,并分别描述驾驶行为
package com.company;
abstract class Transportation
{
abstract void Drive();
}
class Car extends Transportation
{
public void Drive()
{
System.out.println("马路上行驶");
}
}
class Train extends Transportation
{
public void Drive()
{
System.out.println("铁路上行驶");
}
}
class Plane extends Transportation
{
public void Drive()
{
System.out.println("天上行驶");
}
}
public class TaskDay09_2
{
public static void main(String[] args)
{
Car car = new Car();
Train train = new Train();
Plane plane = new Plane();
func(car);
func(train);
func(plane);
}
//多态:父类的引用指向了子类
public static void func(Transportation tool)
{
tool.Drive();
}
}
总结:同样的,这题也是通过多态实现,但是这题是抽象类,但是第2题是接口。
多态的过程细节:多态与继承、方法重写密切相关,我们在方法中接收父类类型作为参数,在方法实现中调用父类类型的各种方法。当把子类作为参数传递给这个方法时,java虚拟机会根据实际创建的对象类型,调用子类中相应的方法(存在方法重写时)。
因此可以继续总结多态实现的三个条件,一定要记下来!
1.需要有继承关系(普通子父类的继承和抽象类的继承)或者实现(接口)的存在。
2.需要有方法的重写。
3.需要有父类的引用指向子类对象。
设计一个保姆类, 保姆需要遵循这些规范
需求:在测试类中,实例化一个保姆的对象,然后让保姆买菜,做饭,扫地
package com.company;
interface Service
{
void wishClothes();
void sweepFloor();
void cookRice();
}
class Nurse implements Service
{
private String name;
Nurse(){}
Nurse(String name)
{
this.name = name;
}
public String getName()
{
return name;
}
public void wishClothes()
{
System.out.println("wishClothes");
}
public void sweepFloor()
{
System.out.println("sweepFloor");
}
public void cookRice()
{
System.out.println("cookRice");
}
}
public class TaskDay09_3
{
public static void main(String[] args)
{
Nurse nurse = new Nurse("Tom");
System.out.println(nurse.getName());
show(nurse);
}
public static void show(Service ser)
{
ser.wishClothes();
ser.sweepFloor();
ser.cookRice();
}
}
这一题同样是用到了多态,和上面两道题不一样的是,这一题里面的子类包含了自己特有的属性,因此先先定义了一个子类对象nurse,利用子类对象nurse对其属性先赋初始值。之后利用多态,创建ser(接口)对象,再将ser对象指向子类对象nurse,实例化的同样只是子类,而不是接口。
经过这三道题目的踪总结,对于多态应当有了更深入的理解。
设计一个猫类,设计一个狗类, 猫和狗都继承自动物类
需求:在测试类中设计一个方法,这个方法需要一个参数,参数的类型可以是猫类,也可以是狗类 -->多态(动物类 )
package com.company;
abstract class Animals
{
private String name;
private String sex;
Animals(){}
Animals(String name, String sex)
{
this.name = name;
this.sex = sex;
}
public void setName(String name)
{
this.name = name;
}
public void setSex(String sex)
{
this.sex = sex;
}
public String getName()
{
return name;
}
public String getSex()
{
return sex;
}
}
class Cat extends Animals
{
Cat(){}
Cat(String name, String sex)
{
super(name, sex);
}
}
class Dog1 extends Animals
{
Dog1(){}
Dog1(String name, String sex)
{
super(name, sex);
}
}
class TaskDay09_4
{
public static void main(String[] args)
{
Cat cat = new Cat("Tom","M");
Dog1 dog1= new Dog1("Amy", "W");
testAnimals(cat);
testAnimals(dog1);
}
public static void testAnimals(Animals ani)
{
if (ani instanceof Cat)
{
//下面这段可以进行封装,但是懒。。。
String name = ani.getName();
String sex = ani.getSex();
System.out.println(name);
System.out.println(sex);
}
if (ani instanceof Dog1)
{
String name = ani.getName();
String sex = ani.getSex();
System.out.println(name);
System.out.println(sex);
}
}
}
总结:认真做到这一道题目的时候已经对面向对象、抽象类、多态有比较深入的理解了!
1.抽象类也是一个类,也应当包含构造方法。
2.子类在继承抽象类时,构造方法应当重写,并继承父类的构造器。
3.为了更加细致地体现面向对象的思想,在main方法中定义的对象应当有明确的指向,例如Cat cat = new Cat(“Tom”,“M”); 此处定义的对象cat应当指向Cat类,而不是指向的Animals类,同时利用构造器对该对象赋初始值更加方便快捷
4.细节上来说,每次重写构造器时都应当写上该类的默认构造器,若不写上,则利用该类作为父类定义子类时,子类找不到父类的默认构造方法出现意想不到的错误。坚持一个良好习惯就成功了一半!
设计一个防水的接口:防水
设计一个手机类,实现这个数据传输接口,采用Type-C;同时实现了防水的接口
package com.company;
interface TypeC
{
}
interface waterProof
{
}
class Phone implements TypeC,waterProof
{
}
public class TaskDay09_5
{
public static void main(String[] args)
{
Phone phone = new Phone();
}
}
总结:实现多个接口
MyArrays.sort(Person[] array, MyComparator comparator);
Person是一个类,MyComparator是一个比较器,包含了compare抽象函数,需要使用匿名内部类重写
package com.company;
interface MyComparator
{
int compare(Person ren1, Person ren2);
}
class Person
{
private String name;
private int age;
public Person(){}
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public int getAge() {
return age;
}
//重写toString方法
public String toString()
{
return name+"," +age;
}
}
public class TaskDay09_6 {
public static void main(String[] args)
{
Person[] arr = {new Person("lisi", 20), new Person("zhosi", 35),
new Person("wangzi", 18), new Person("gangzi", 40), };
sort(arr, new MyComparator(){
public int compare(Person ren1, Person ren2)
{
return ren1.getAge() - ren2.getAge();
}
});
for (Person person:arr)
{
System.out.println(person.toString());
}
}
//选择排序,排序器用来比较大小的,只有这么一个功能
public static void sort(Person[] array, MyComparator comparator)
{
for (int i=0; i<array.length-1; i++)
{
for(int j=i+1; j<array.length; j++)
{
if(comparator.compare(array[j], array[i])>0)
{
Person temp = array[j];
array[j] = array[i];
array[i] = temp;
}
}
}
}
}
按照题目要求做即可,这里对Person排序指的是对Person里的age排序。
比较震撼的是lambda表达式,idea直接可以将匿名内部类换成lambda表达式,期待后面的学习