【原】Java学习笔记019 - 面向对象

时间:2023-03-09 02:15:18
【原】Java学习笔记019 - 面向对象
 package cn.temptation;

 public class Sample01 {
public static void main(String[] args) {
// 仔细想一想,Animal应该是一个抽象的概念,相对于Animal来说,狗才是具体的概念
// Animal的行为也应该算是一个抽象的行为 // Java中对于这些抽象的概念或是抽象的行为,提供了一个关键字 abstract 来进行修饰 // 关键字 abstract用在类上,类称为抽象类:abstract class 类名
// 关键字 abstract用在方法上,方法称为抽象方法:abstract 返回类型 方法名(参数列表) // 抽象类不能进行实例化
// 原因:既然这个Animal类都是抽象的概念了,自然无法具体的创建出一个对象来,所以不能被实例化
// 语法错误:Cannot instantiate the type Animal
// Animal animal = new Animal(); // 抽象类不能直接实例化使用,但是可以通过继承使用,使用多态写法
// Animal animal = new Dog();
// 对于子类的成员方法,编译看赋值号左边,执行看赋值号右边
// animal.eat();
}
} //// 抽象类
//abstract class Animal {
// // 成员方法
// // 语法错误:Abstract methods do not specify a body 抽象方法没有方法体
//// public abstract void eat() {
//// System.out.println("动物会吃");
//// }
//
// // 成员方法上使用了abstract,就变成了一个抽象成员方法
// // 没有方法体,意味着没有具体的实现,只是定义
// public abstract void eat();
//}
//
//// 具体实现子类
//class Dog extends Animal {
// @Override
// public void eat() {
// System.out.println("狗会吃");
// }
//}
 package cn.temptation;

 public class Sample02 {
public static void main(String[] args) {
// 抽象类 和 抽象成员方法的特点:
// 1、抽象类中可以有抽象的成员方法,也可以有非抽象的成员方法
// 2、只要类中有抽象的成员方法,该类就必须得是抽象类
// 3、抽象的成员方法没有方法体,只有小括号没有大括号,但是有分号作为结尾
// 4、抽象类不能被实例化,因为它被修饰为抽象的
// 5、抽象类可以有构造函数;虽然其构造函数不是用来做实例化的操作,但是可以提供给其子类创建对象时使用
// 6、抽象类的子类也可以是一个抽象类
// 7、不论抽象类中的成员方法是否为抽象的,只要类是抽象的,就不能实例化,也就不能使用对象名.成员方法来进行调用
}
} // 抽象父类
abstract class Animal {
// 构造函数
public Animal() {
System.out.println("无参构造函数");
} // 成员方法
// 抽象的成员方法
public abstract void eat(); // 非抽象的成员方法
public void sleep() {
System.out.println("动物能睡觉");
}
} // 抽象子类
abstract class Dog extends Animal { } // 抽象子类的具体实现的孙类
class ChineseDog extends Dog {
@Override
public void eat() {
System.out.println("中国狗会吃");
}
} // The abstract method test in type Demo can only be defined by an abstract class
//class Demo {
// // 抽象的成员方法
// public abstract void test();
//}
 package cn.temptation;

 public class Sample03 {
public static void main(String[] args) {
// 抽象类成员的使用问题:
// 1、成员变量:可以是变量,也可以是自定义常量
// 2、构造函数:构造函数不是用来做实例化的,但是是提供给子类使用的
// 3、成员方法:可以是抽象的,也可以是非抽象的
// 抽象的成员方法:强制具体实现子类实现父类的抽象成员方法
// 非抽象的成员方法:子类可以重写、也可以不重写 Human human = new Man();
System.out.println(human.i);
System.out.println(human.X);
}
} // 抽象类
abstract class Human {
// 成员变量
public int i = 2;
public final int X = 3; // 构造函数(无参)
public Human() {
System.out.println("无参构造函数");
} // 构造函数不能使用abstract修饰
// 语法错误:Illegal modifier for the constructor in type Human; only public, protected & private are permitted
// public abstract Human(); // 构造函数(有参)
public Human(int i) {
this.i = i;
System.out.println(i);
} // 成员方法
// 抽象的成员方法
public abstract void eat(); // 非抽象的成员方法
public void sleep() {
System.out.println("人能睡觉");
}
} // 具体实现子类
class Man extends Human {
// 构造函数
public Man() {
super(99);
} // 成员方法
// 不重写就会生成语法错误
// 语法错误:The type Man must implement the inherited abstract method Human.eat() Sample03.java /Day20170302_OOP/src/cn/temptation line 48 Java Problem
// 重写抽象的成员方法
public void eat() { }
}
 package cn.temptation;

 public class Sample04 {
public static void main(String[] args) {
// 调用抽象类的静态成员变量 和 静态成员方法,使用类名.静态成员,无视该类是否为抽象类
// System.out.println(Phone.number);
// Phone.call();
}
} abstract class Phone {
// 静态成员变量
// static int number = 110; // 静态成员方法
// static void call() {
// System.out.println("打电话");
// } // 抽象的成员方法
public abstract void method1(); // private 和 abstract同时修饰,语法错误。
// 理解:private要求的是私有的,而abstract提出抽象的概念,需要后代去做实现,所以语义上是矛盾的
// 语法错误:The abstract method method2 in type Phone can only set a visibility modifier, one of public or protected
// private abstract void method2(); // final 和 abstract同时修饰,语法错误。
// 理解:final要求的是子类不能重写父类的成员方法,而abstract提出抽象的概念,需要后代去做实现,所以语义上是矛盾的
// 语法错误:The abstract method method3 in type Phone can only set a visibility modifier, one of public or protected
// final abstract void method3(); // static 和 abstract同时修饰,语法错误。
// 理解:static要求的是对象们(类的)的成员方法,而abstract提出抽象的概念(不是具体的),所以语义上是矛盾的
// 语法错误:The abstract method method4 in type Phone can only set a visibility modifier, one of public or protected
// static abstract void method4();
}
 package cn.temptation;

 public class Sample05 {
public static void main(String[] args) {
// 需求:使用学过的知识点实现
// 东汉公司的员工都不睡觉
// 1、东汉公司的码农 吕布 是公司的员工,他写代码、打游戏,拿很少的薪水(1680)
// 2、东汉公司的经理 貂蝉 也是公司的员工,她做管理、听音乐,拿很多的薪水(20000) Staff.companyName = "东汉"; Staff staff1 = new Programmer("吕布", 1680);
System.out.println("姓名为:" + staff1.getName() + ",薪资为:" + staff1.getSalary() + ",公司名为:" + Staff.companyName);
staff1.nosleep();
staff1.work();
((Programmer)staff1).playGame(); Staff staff2 = new Manager();
staff2.setName("貂蝉");
staff2.setSalary(20000);
System.out.println("姓名为:" + staff2.getName() + ",薪资为:" + staff2.getSalary() + ",公司名为:" + Staff.companyName);
staff2.nosleep();
staff2.work();
((Manager)staff2).listenMusic();
}
} /**
* 抽象类:员工类
*/
abstract class Staff {
// 成员变量
// 名字
private String name;
// 薪资
private int salary;
// 公司名
public static String companyName; // 构造函数(无参)
public Staff() { } public Staff(String name, int salary) {
super();
this.name = name;
this.salary = salary;
} // 成员方法
public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} public int getSalary() {
return salary;
} public void setSalary(int salary) {
this.salary = salary;
} // 自定义成员方法
/**
* 抽象成员方法:工作
* 等着具体实现子类去进行实现
*/
public abstract void work(); /**
* 非抽象成员方法:不睡觉
* 不想被子类重写,可以使用final进行修饰
*/
public final void nosleep() {
System.out.println("不睡觉");
}
} /**
* 子类:程序员类
*/
class Programmer extends Staff {
// 成员变量 // 构造函数
public Programmer() {
super();
} public Programmer(String name, int salary) {
super(name, salary);
} // 成员方法
@Override
public void work() {
System.out.println("写代码");
} public void playGame() {
System.out.println("打游戏");
}
} /**
* 子类:经理类
*/
class Manager extends Staff {
// 成员方法
@Override
public void work() {
System.out.println("做管理");
} public void listenMusic() {
System.out.println("听音乐");
}
}
 package cn.temptation;

 public class Sample06 {
public static void main(String[] args) {
// Bird bird1 = new Eagle(); // 老鹰是一种鸟
// bird1.fly();
//
// Bird bird2 = new Sparrow(); // 麻雀是一种鸟
// bird2.fly();
//
// Bird bird3 = new Plane(); // 飞机是一种鸟
// bird3.fly();
}
} //// 抽象类:鸟类
//abstract class Bird {
// // 抽象方法:飞行
// public abstract void fly();
//}
//
//// 具体子类:老鹰类
//class Eagle extends Bird {
// @Override
// public void fly() {
// System.out.println("老鹰的飞行");
// }
//}
//
//// 具体子类:麻雀类
//class Sparrow extends Bird {
// @Override
// public void fly() {
// System.out.println("麻雀的飞行");
// }
//}
//
//// 为了让飞机能飞行,强行让飞机从抽象父类鸟类进行继承,这样很别扭
//// 究其原因,因为子类继承父类,得到了父类的特征和行为(非私有的),这是一种先天的联系
//// 但是,在现实的世界中,除了描述先天上的联系,还有描述后天的关联
//// 这里的飞机会飞行,这不是先天上的天赋,而是后天具有的能力
//// 对于这些后天具备的能力,还去使用描述先天联系的继承去实现,就显得别扭了
//
//// 对于描述后天具备的能力,Java中提供了 接口(interface) 机制
//
//// 具体子类:飞机类
//class Plane extends Bird {
// @Override
// public void fly() {
// System.out.println("飞机的飞行");
// }
//}
 package cn.temptation;

 public class Sample07 {
public static void main(String[] args) {
// 接口:描述事物具有的能力 // 格式:interface 接口名 { ... } // 接口的实现形式: class 类名 implements 接口名 { .... } // 注意:
// 1、接口不能实例化
// 2、如何使用接口?
// A:通过实现接口的类使用接口
// B:重写接口中定义的成员方法(类似抽象类的实现子类中的重写) // 语法错误:Cannot instantiate the type Ability
// Ability ability = new Ability(); // 常规写法(类的实例化)
// Plane plane = new Plane();
// plane.fly(); // 多态写法
// Ability plane = new Plane(); // 飞机具备能力
// plane.fly(); // 关于多态及其重写使用的场合:
// 1、非抽象类继承后的多态(不常见)
// 2、抽象类继承后的多态(常见)
// 3、接口实现后的多态(常见)
}
} //// 接口:能力接口
//interface Ability {
// // 接口中的方法没有方法体
// // 语法错误:Abstract methods do not specify a body
//// public void fly() {
////
//// }
//
// // 接口中的方法必须是抽象的
// public abstract void fly();
//}
//
//// 具体的飞机类 实现 能力接口
//class Plane implements Ability {
// @Override
// public void fly() {
// System.out.println("飞机 的飞行");
// }
//}
 package cn.temptation;

 public class Sample08 {
public static void main(String[] args) {
// 接口的成员:
// 1、成员变量:
// 接口中的成员变量支持的修饰符:public static final 数据类型 成员变量名
// 通过对接口的字节码文件的反编译,发现接口中的成员变量的修饰符都是public static final修饰的,也就是这些成员变量都是接口的自定义常量
// 2、构造函数
// 接口不能有构造函数(接口不能实例化)
// 3、成员方法
// 接口中的方法必须是抽象的,不能是非抽象的
// 接口中的所有方法(都是抽象方法)必须要在实现类中进行实现
Test obj = new TestImpl();
System.out.println(obj.i);
System.out.println(obj.j);
System.out.println(obj.k); // 语法错误:The final field Test.i cannot be assigned
// obj.i = 99; // 注意:"不能实例化的就一定没有构造函数"这种说法对不对? 答:不对,例如:抽象类
}
} // 接口
interface Test {
// 成员变量
public int i = 2;
public final int j = 4;
public static final int k = 6;
// 语法错误:Illegal modifier for the interface field Test.x; only public, static & final are permitted
// private int x = 99; // 构造函数
// 语法错误:Interfaces cannot have constructors
// public Test() {
//
// } // 成员方法
// 非抽象的成员方法
// 语法错误:Abstract methods do not specify a body
// public void method() {
//
// } // 抽象的成员方法
public abstract void method1();
// 语法错误:Illegal modifier for the interface method method2; only public, abstract, default, static and strictfp are permitted
// private abstract void method2();
} // 接口的实现类
class TestImpl implements Test {
@Override
public void method1() { }
}
 package cn.temptation;

 public class Sample09 {
public static void main(String[] args) {
// 1、类 和 类之间的关系
// 类和类之间可以是继承的关系(extends 关键字 inheritance)
// Java中的继承(针对类)是单继承,可以有继承链 // 2、类 和 接口之间的关系
// 类和接口之间是实现的关系(implements 关键字 implement)
// Java中的实现可以是单实现(具备某一种能力),也可以是多实现(具备多种能力)
// 注意:类与接口之间是实现的关系,没有继承的关系 // 3、接口 和 接口之间的关系
// 接口 和 接口之间可以是单继承,也可以是多继承
// 注意:接口不能实现另一个接口,因为接口定义的是规范,不是实现 // 面试题:
// Java语言是单继承、多实现的(×)
// 答:对于类,是单继承、多实现的;对于接口,是可以单继承,也可以多继承,但是不能实现其他接口或类
}
} class GrandFather { } class Father extends GrandFather { } class Mother { } // 语法错误:Syntax error on token ",", . expected
//class Son extends Father, Mother {
// 语法错误:The type Eat cannot be the superclass of Son; a superclass must be a class
//class Son extends Eat {
class Son extends Father implements Eat, Sleep { } interface Eat { } interface Sleep { } // 接口可以多继承
//interface Lazy extends Eat, Sleep {
//
//} // 语法错误:Syntax error on token "implements", extends expected
//interface Lazy implements Eat {
//interface Lazy implements Sleep {
//}
 package cn.temptation;

 public class Sample10 {
public static void main(String[] args) {
// 抽象类 和 接口的区别
/*
* 1、成员上的区别:
* 抽象类:
* A:成员变量:可以是变量,也可以是常量
* B:构造函数:有,但是不能实例化,只能供子类调用
* C:成员方法:可以有抽象的成员方法,也可以有非抽象的成员方法
*
* 接口:
* A:成员变量:都是常量(自定义常量)
* B:构造函数:没有构造函数
* C:成员方法:都是抽象的成员方法
*
* 2、关系上的区别:
* 类和类:单继承
* 类和接口:类可以是单实现接口,也可以是多实现接口
* 接口和接口:接口可以是单继承接口,也可以是多继承接口
*
* 3、设计意图上的区别:
* 抽象类:描述的是先天的天赋,有着抽象的概念、抽象的行为和具体实现子类是继承的关系,对于继承的具体实现子类来说描述了"is a(an)"的含义
* 抽象类中定义的成员是这些子类以及它们的后代共有的特征和行为(且不好具体描述)
* 接口:描述的是后天培养的、具备的能力,供类实现或是给其他接口继承,描述的是"like a(an)"或"as a(an)"的含义
* 接口中定义的是被实现的类需要扩展的功能
*/ // 【面向对象设计原则之一:"开闭原则"-----"对扩展开放,对修改封闭"】
// 换句话说,在面向对象的设计中,建议多使用接口,少使用继承
// 对于接口,应该理解其"规范性、强制性"的特点
}
} // 接口:能力接口
interface Ability {
// 接口中的方法必须是抽象的
public abstract void fly();
} class Plane implements Ability {
// 实现了Ability接口,具备了接口定义的能力(方法)
@Override
public void fly() {
System.out.println("飞机能飞");
}
}
 package cn.temptation;

 public class Sample11 {
public static void main(String[] args) {
// 需求:使用学过的知识(例如:抽象类、接口等)实现如下功能
// 1、吕布是个体育系的男学生,20岁,学习Java,会打篮球(因为是体育系的)
// 2、貂蝉是个音乐系的女学生,16岁,学习乐理,会弹棉花(因为是音乐系的) Student student1 = new PE("吕布", 20, "男");
student1.study("Java");
((PE)student1).doSport("篮球"); Student student2 = new MusicalStudent("貂蝉", 16, "女");
student2.study("乐理");
((MusicalStudent)student2).doEquipment("棉花");
}
} // 抽象类:学生类
abstract class Student {
// 成员变量
// 姓名
private String name;
// 年龄
private int age;
// 性别
private String gender;
// 系别
public static String dept = ""; // 构造函数
public Student() {
super();
} public Student(String name, int age, String gender, String dept) {
super();
this.name = name;
this.age = age;
this.gender = gender;
Student.dept = dept; System.out.println("姓名为:" + this.name + ",年龄为:" + this.age + ",性别为:" + this.gender + ",系别为:" + Student.dept);
} // 成员方法
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;
} public String getGender() {
return gender;
} public void setGender(String gender) {
this.gender = gender;
} // 自定义的成员方法
// 考虑到学生先天的天赋行为有学习,所以在抽象类中制作一个抽象方法study
public abstract void study(String course);
} /**
* 具体实现子类:体育系学生
*/
class PE extends Student implements Sport {
// 成员变量
// 考虑到系别是子类的特征,所以定义为static
public static String dept = "体育系"; // 构造函数
public PE() {
super();
} public PE(String name, int age, String gender) {
super(name, age, gender, PE.dept);
} // 成员方法
@Override
public void study(String course) {
System.out.println("学习" + course);
} @Override
public void doSport(String sportName) {
System.out.println("做" + sportName + "运动");
}
} /**
* 具体实现子类:音乐系学生
*/
class MusicalStudent extends Student implements Equipment {
// 成员变量
// 考虑到系别是子类的特征,所以定义为static
public static String dept = "音乐系"; // 构造函数
public MusicalStudent() {
super();
} public MusicalStudent(String name, int age, String gender) {
super(name, age, gender, MusicalStudent.dept);
} // 成员方法
@Override
public void study(String course) {
System.out.println("学习" + course);
} @Override
public void doEquipment(String equipmentName) {
System.out.println("演奏" + equipmentName + "器械");
}
} // 运动能力接口
interface Sport {
public abstract void doSport(String sportName);
} // 器械能力接口
interface Equipment {
public abstract void doEquipment(String equipmentName);
}