【原】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);
}
【原】Java学习笔记019 - 面向对象的更多相关文章
- Java学习笔记之---面向对象
Java学习笔记之---面向对象 (一)封装 (1)封装的优点 良好的封装能够减少耦合. 类内部的结构可以自由修改. 可以对成员变量进行更精确的控制. 隐藏信息,实现细节. (2)实现封装的步骤 1. ...
- Java学习笔记之面向对象、static关键字
一周Java学习总结 今天就总结理清一下关于面向对象和面向过程的程序设计的一些不同特点,以及讲下static关键字. 面向对象 现在接触的Java是面向对象的,现在的程序开发几乎都是以面向对象为基础的 ...
- Java 学习笔记(4)——面向对象
现在一般的语言都支持面向对象,而java更是将其做到很过分的地步,java是强制使用面向对象的写法,简单的写一个Hello Word都必须使用面向对象,这也是当初我很反感它的一点,当然现在也是很不喜欢 ...
- 【原】Java学习笔记016 - 面向对象
package cn.temptation; public class Sample01 { public static void main(String[] args) { // this 关键字 ...
- 【原】Java学习笔记014 - 面向对象
package cn.temptation; public class Sample01 { public static void main(String[] args) { // 面向对象思想 // ...
- 【原】Java学习笔记020 - 面向对象
package cn.temptation; public class Sample01 { public static void main(String[] args) { // 成员方法的参数列表 ...
- 【原】Java学习笔记018 - 面向对象
package cn.temptation; public class Sample01 { public static void main(String[] args) { // 继承关系的子类可以 ...
- 【原】Java学习笔记017 - 面向对象
package cn.temptation; public class Sample01 { public static void main(String[] args) { // 继承关系中的pri ...
- 【原】Java学习笔记015 - 面向对象
package cn.temptation; public class Sample01 { public static void main(String[] args) { // 传递 值类型参数 ...
随机推荐
- mybatis xml < >
[参考文章]:mybatis 中的 xml 配置文件中 ‘<’. ‘>’ 处理 1.使用转义字符将 ‘<’. ‘>’ 替换掉 描述 字符 转义字符小于号 < <大于 ...
- Kubernetes因限制内存配置引发的错误
今天对一个pod进行内存资源调整后, 一直卡在ContainerCreating的状态, 执行describe命令查看该 Pod 详细信息后发现如下 . [root@master-01 ~]# kub ...
- presto中ldaps配置完整流程
最近开始转战presto,至于前面章节中的Hbase,我也会持续更新,喜欢我的可以关注我.关于这个流程,我看过阿里云的的一篇文章,但看后还是不知所云,就写下了这篇博客,大家感兴趣的可以访问那篇文章—— ...
- VirtualBox虚拟机克隆迁移步骤
VirtualBox是常用的虚拟机管理软件,和VMware一样,用的很多.在使用过程中,有的时候需要对虚拟机进行迁移.比如我们原来的服务器,使用的win10操作系统,上面利用VirtualBox安装了 ...
- Java中的String,StringBuilder,StringBuffer三者的区别(转载)
最近在学习Java的时候,遇到了这样一个问题,就是String,StringBuilder以及StringBuffer这三个类之间有什么区别呢,自己从网上搜索了一些资料,有所了解了之后在这里整理一下, ...
- spark能传递外部命名参数给main函数吗?
查了资料好像都没有办法.只能通过: def main(args: Array[String]): Unit = { // 读取参数 var city = args(0) var input = arg ...
- 【ASP.NET Core快速入门】(六)配置的热更新、配置的框架设计
配置的热更新 什么是热更新:一般来说,我们创建的项目都无法做到热更新:即项目无需重启,修改配置文件后读取到的信息就是修改配置之后的 我们只需要吧项目中用到的IOptions改成IOptionsSnap ...
- leetcode — largest-rectangle-in-histogram
import java.util.Stack; /** * * Source : https://oj.leetcode.com/problems/largest-rectangle-in-histo ...
- 痞子衡嵌入式:史上最强ARM Cortex-M学习资源汇总(持续更新中...)
大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是ARM Cortex-M学习资源. 类别 资源 版本 短评 官方汇总 cortex-m-resources / ARM公司专家Josep ...
- [JavaScript] 后端js的模块化规范CommonJs
CommonJs概述 主要是单个文件定义的变量,函数,类都是私有的,其他文件不可见,单位的作用域 通过 exports(modules.exports)对外暴露接口,通过 require 加载模块 n ...