JAVA面向对象笔记
未经作者同意,禁止转载文章

来到这一章,说明你已经经过前面的新手村了(JAVA基础知识笔记),接下来的将会遇到些神秘莫测的妖魔鬼怪—-抽象怪。在前面的章节算是知道Java的一些浅浅的基本规则,懂得他的格式语法,学习到他的代码处理逻辑,例如,掌握基础语法、数据类型、控制结构(如 iffor)、类和对象等概念。伴随学习的过程中,偶尔会刷新出一些小怪(练习题)来热身找找手感。面向对象编程有四大原则:封装(隐藏内部细节,提供接口)、继承(子类复用父类属性和方法)、多态(同一操作在不同对象上有不同表现)和抽象(定义通用行为,隐藏具体实现)。接下来就开始这段新的征程吧。

面向对象的概述

什么是对象

万物皆对象,客观存在的事物都是对象,大到名胜古迹,小到剪刀、钟表、信封等

什么是类

类是对现实生活中一类具有共同属性和行为的事物的抽象
类是对象的数据类型,类是具有相同属性和行为的一组对象的集合
简单理解:类就是对现实事物的一种描述

什么是对象属性

属性:对象具有的各种特征,每个对象的每个属性都拥有特定的值。

什么是对象的行为

行为对象能够执行的操作

类和对象的关系

类:类是对现实生活中一类具有共同属性和行为的事物的抽象
对象:是能够看得到摸的着的真实存在的实体
简单理解:类是对事物的一种描述,对象则为具体存在的事物
类是对象的抽象,对象是类的实体

类的定义

1.类的重要性:类是java程序的基本组成单位
类是什么:是对现实生活中一类具有共同属性和行为的事物的抽象,确定对象将会拥有
的属性和行为

2.类的组成:(属性和行为)
属性 在类中通过成员变量来体现 (类中方法外的变量)
行为在类中通过成员方法来体现 (和前面的方法相比去掉static关键字即可)

类的定义步骤

1.定义类
public class 类名称{
  1.成员属性(参数)
  2.成员方法(行为)
}
2.定义成员变量
属性类型 属性名称;
3.定义成员方法
public 返回类型 方法名(){
}

对象的使用

1.创建对象
格式:类名 对象名= new 类名();
范例: Phone phone1 =new Phone();
2.使用对象
2.1使用成员变量
格式:对象名称.变量
范例: phone1 .brand=”xiaomi”;
2.2使用成员方法
格式:对象名称.方法名
范例:phone1.call();

学生对象案例

需求:首先定义一个学生类,在定义一个学生测试类,在学生测试类中通
过对象完成成员变量和成员方法的使用

package com.siyi.test;

public class Student {
    public String name;
    public int age;

    public void produce(String name, int age) {
        System.out.println("Name: " + name + ", Age: " + age);
    }
}

===============================================


package com.siyi.test;

import java.util.Scanner;

public class test {
    public static void main(String[] args) {
        Student stu1=new Student();
        stu1.name="罗杰";
        stu1.age=20;
        stu1.produce(stu1.name, stu1.age);
    }
}

成员变量与局部变量的区别

1.什么是成员变量与局部变量
成员变量:类中的方法外的变量 就是为成员变量
局部变量:方法中的变量 局部变量

区别成员变量局部变量
类中位置不同类中方法外类中方法里
内存中位值堆内存栈内存
生命周期不同随对象存在而存在,随对象消失而消失随方法调用存在而存在,随方法结束消失而消失
初始化值不同有默认的初始化值没有默认的初始化值,必须先定义赋值后使用

访问修饰符之private

1.是一个权限修饰符;
2.可以修饰成员变量和成员方法;
3.被其修饰的成员只能在本类中被访问,可以保护成员不被其他类使用。
1.提供“get变量名()”方法,用于获得成员变量的值,方法用public修饰
2.提供“set变量名(参数)”方法,用于设置成员变量的值,方法用public修饰

package com.siyi.test;

public class Student {
    public String name;
    private int age;

    public void setAge(int age){
      if(age>120 || age<0){
        System.out.println("所赋值的年龄,是不正确的");
        return;
      }
      this.age = age;
    }
    public int getAge(){
      return this.age;
    }
    
    public void produce(String name, int age) {
        System.out.println("Name: " + name + ", Age: " + age);
    }
}

===============================================


package com.siyi.test;

import java.util.Scanner;

public class test {
    public static void main(String[] args) {
        Student stu1=new Student();
        stu1.name="罗杰";
        stu1.setAge(88);
        stu1.produce(stu1.name, stu1.getAge());
    }
}

this关键字

this修饰的变量用于指代成员变量
方法的形参如果与成员变量同名,不带this修饰的变量指的是形参
方法的形参没有与成员变量同名,不带this修饰的变量指的是成员变量

什么时候用this?解决局部变量隐藏成员变量
this:代表所在的类对象的引用
方法被哪个对象调用,this就代表哪个对象

this使用细节

1.this关键字可以用来访问本类的属性、方法、构造器
2.this用于区分当前类的属性和局部变量
3.访问成员方法的语法:this.方法名(参数列表)
3.访问构造器语法:this(参数列表);注意只能在构造器使用(即只能在构造器中访问另外一个构造器)
必须放在第一条语句
4.this不能在类定义的外部使用,只能在类定义的方法中使用

构造方法

构造方法是一种特殊的方法
作用创建对象
注意:构造方法方法的名称一定与类的名称是一样

public class Student{
  修饰符 类的名称(参数){
  
  }
}

功能:主要是完成对象数据的初始化

构造方法的创建
1.如果没有定义构造方法,系统将给出一个默认的无参构造方法
2.如果定义了构造方法,系统将不再提供默认的构造方法

方法重载:构造方法名称相同但是参数列表不同这就是重载。
注意:如果自定义了带参数的构造方法,还要使用无参数构造方法,就必须要写一个无参构造方法

构造方法的作业题

1 成员变量
使用Jprivate修饰
2 构造方法
提供一个无参构造方法
提供一个带多个参数的构造方法
3成员方法
提供每一个成员变量对应的setXxx () /getXxx ()
提供一个显示对象信息的toStringO)
4(测试类)创建对象并为其成员变量赋值的两种方式
无参构造方法创建对象后使用setXxx()赋值
使用带参构造方法直接创建带有属性值的对象

package com.siyi.test;

public class Student {
    private String name;
    private int age;
    
    public Student() {
        System.out.println("无参构造方法");
    }
    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public void setName(String name) {
        this.name = name;
    }
    public void setAge(int age) {
        this.age = age;
    }
    public String getName() {
        return name;
    }
    public int getAge() {
        return age;
    }
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}


=============================================================

package com.siyi.test;

import java.util.Scanner;

public class test {
    public static void main(String[] args) {
        Student s1 = new Student();
        s1.setName("张三");
        s1.setAge(23);
        System.out.println(s1.toString());
        Student s2 = new Student("李四", 24);
        System.out.println(s2.toString());
    }
}

封装

面向对象的三个基本特征(oop)之一:(封装、继承、多态)
封装,也就是把客观事物封装成抽象的类,并且类可以把自己的数据和方法只让可信的类或者对象操作,
对不可信的进行信息隐藏。

封装的规则:
1.将类的某些信息隐藏在类的内部,不允许外部的程序直接访问;
2.通过该类提供的方法来实现对隐藏信息的操作和访问;

封装的实现:
1.修改属性私有(设为private)
2.创建getter/setter方法(设为public用于属性的读写)
3.在getter/setter方法中加入属性控制语句(对属性的合法性进行判断)

继承

继承是面向对象的三大特征之一,可以使得子类具有父类的属性和方法,还可以在子类中重新定义、追
加属性和方法

继承的格式:
public class 子类名 extends 父类名{}

父类:也被称为基类、超类
子类:也被称为派生类
范例:public class Student extends Parent{}

public class Parent{
  private String username;
  private int age;
  
  public String getUserName(){
    return username;
  }
  
  public String setUserName(){
    this.userName = username;
  }
  
  public String getAge(){
    return age;
  }
  
  public String setAge(){
    this.userAge = age;
  }
}


public class student extends Parent{
  public static void main(String[] args){
    Student s = new Student();
    String userName = s.getUserName;
  }

继承优缺点

1.好处:
提高了代码的复用性 (多个类相同的成员属性和方法可以放到一个类当中)
提高了代码的维护性(如果方法的代码需要修改,只需修改一处即可)
2.弊端:
继承让类与类之间产生了关系,类的耦合性也增加了,当父类发生变化时候,子类也不得不跟着变化,
削弱了子类的独立性。

什么是使用继承?
假设法:我有两个类A和B,如果满足A是B的一种,或者B是A的一种,就说明他们存在继承关系,这个时
候就可以考虑使用继承,否则不能滥用继承。
苹果和水果/猫和动物狗和狮子

继承中变量的访问特点

在子类方法中访问一个变量:
子类局部范围找
子类成员范围找
父类成员范围找
如果都没有则报错
即遵循就近原则!

super关键字的用法和this关键字相似

1.this:代表本类对象的引用
2.super:代表父类存储空间的标识(可以理解为父类对象的引用)

关键字访问成员变量访问构造方法访问成员方法
thisthis.成员变量(访问本类的成员变量)this(..)(访问本类的构造方法)this.成员方法()(访问本类的成员
方法)
supersuper.成员变量(访问父类的成员变量)super(..)(访问父类的构造方法)super.成员方法()(访问父类的成员
方法)

继承中构造方法的访问特点

1.子类中所有的构造方法默认都会访问父类中的无参的构造方法
2.因为子类会继承父类中的数据,可能还会使用父类中的数据,所以子类初始化之前,需要对父类进行
初始化。
3.每个子类构造方法的第一句默认都是:super()

如果父类中没有无参构造方法,只有带参构造方法,怎么办?
1.通过super关键字显示调用父类的有参构造方法
2.父类中自己单独定义一个无参构造方法

方法重写

概述:
子类中出现了和父类一模一样的方法
当子类需要父类的功能,而功能主体中,子类有自己独特的内容,就可以通过重写父类中的方法,这样
即延续了父类的功能,又定义了自己的特有内容

@Override
是一个注解(注解后面会学习到)
可以帮我们检查重写方法声明的正确性

方法重写注意事项

1.(私有的方法不能被重写)父类中私有方法,子类不能被继承
2.子类方法访问权限不能比父类低 (public>默认>私有的)

权限修饰符

Java有四种访问权限,其中三种有访问权限修饰符,分别为private,public和protected,还有一种不
带任何修饰符:

1.private:Java语言中对访问权限限制的最窄的修饰符,一般称之为“私有的”。被其修饰的类、属性
以及方法只能被该类的对象访问,其子类不能访问,更不能允许跨包访问。
2.default:即不加任何访问修饰符,通常称为“默认访问模式“。该模式下,只允许在同一个包中进行
访问。
3.protect:介于public 和 private 之间的一种访问修饰符,一般称之为“保护形”。被其修饰的类、
属性以及方法只能被类本身的方法及子类访问,即使子类在不同的包中也可以访问。需要继承
4.public:Java语言中访问限制最宽的修饰符,一般称之为“公共的”。被其修饰的类、属性以及方法
不仅可以跨类访问,而且允许跨包(package)访问。

权限修饰符同一个类同一个包不同包的子类不同包的非子类
private(私有)×××
default (默认)××
protected(受保护的)×
public(公开)

java中继承注意事项

1.java中类只支持单继承,不支持多继承(一个子类不能有两个父类)
2.java中类支持多层继承

继承作业题

1.继承的思想实现猫和狗的案例,并在测试类中进行测试。
猫和狗–共同特性都是属于动物
①定义动物类(Animal)
成员变量:姓名,年龄
构造方法:无参,带参
成员方法:get/set方法
②定义猫类(Cat),继承动物类
构造方法:无参,带参
成员方法:抓老鼠(catchMouse)
③定义狗类(Dog),继承动物类
构造方法:无参,带参
成员方法:看门(lookDoor)
④定义测试类(AnimalDemo),写代码测试

public class Animal {
    private String name;
    private int age;
    public Animal(String name, int age) {
        this.name = name;
        this.age = age;
    }
    public Animal() {}

    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 class Dog extends Animal{
    public Dog(String name, int age) {
        super(name, age);
    }
    public Dog() {
    }
    public void lookHome() {
        System.out.println("看家");
    }
}

====================================================

public class Cat extends Animal {
    public Cat(String name, int age) {
        super(name, age);
    }
    public Cat() {
    }
    public void catchMouse() {
        System.out.println("抓老鼠");
    }
}

====================================================

public class test {
    public static void main(String[] args) {
        Dog dog = new Dog("旺财", 18);
        Cat cat = new Cat("来财", 13);
        System.out.println("狗的名字:" + dog.getName() + ",年龄:" + dog.getAge());
        System.out.println("猫的名字:" + cat.getName() + ",年龄:" + cat.getAge());
        Dog dog2 = new Dog();
        Cat cat2 = new Cat();
        dog2.setName("小黄");
        dog2.setAge(3);
        cat2.setName("小花");
        cat2.setAge(2);
        System.out.println("狗的名字:" + dog2.getName() + ",年龄:" + dog2.getAge());
        System.out.println("猫的名字:" + cat2.getName() + ",年龄:" + cat2.getAge());
    }
}

包(package):其实就是文件夹。
作用:对类进行分类管理。
包的定义格式
格式:package 包名 (多级包用.分开)
范例:package com. siyi.day01

Siyi
带包的Java类编译和执行
1.手动建包:
按照以前的格式编译Java文件javac Siyi.java
手动创建包com#mayikt文件夹 把classcom#siyi文件夹下即可。
2.自动建包 javac -d.Siyi. java带包执行java com.siyi.Siyi
注意我们类名称是通过全限定名(包的名称)+类的名称组合

import(导入包)

使用不同包下的类时,使用的时候需要写类的全路径,为了简化
带包的操作,我们就可以使用import
导包的格式:
1.格式:import com.siyi.m1

状态修饰符

1.final (最终态)
2.static (静态)

final关键字修饰我们的类、成员属性、成员方法
1.被final关键字修饰的类 无法被继承-
2.被final关键字修饰成员方法无法被重写的
3.被final关键字成员属性该变量的值(必须初始化该值))无法被修改的

final修饰的局部变量
基本数据类型:final修饰的基本数据类型的值不能够被修改的;
引用数据类型:final修饰的引用数据类型引用类型地址不能够发生变化的,但是引用类型的
地址里面的值是可以发生变化的。

static
static翻译中文“静态”的意思,可以修饰成员方法、成员变量。
static修饰的特点:被类的所有对象共享访问。

static访问特点:
非静态成员方法
1.能够访问静态的成员变量;
2.能够访问非静态的成员变量;
3.能够访问静态的成员方法;
4.能够访问非静态的成员方法;
静态的成员方法
1.能够访问静态成员变量,但是不能够直接访问成员变量
2.能够访问静态的成员方法,但是不能够直接访问成员方法

static关键字的用途
一句话描述就是:方便在没有创建对象的情况下进行调用 (方法/变量)。
显然,被static关键字修饰的方法或者变量不需要依赖于对象来进行访问,只要类被加载了,就可以通
过类名去进行访问。
static可以用来修饰类的成员方法、类的成员变量,另外也可以编写static代码块来优化程序性能

main方法的深入理解

深入理解main方法 public static void main(String[ ] args)
1、main方法是Java虚拟机在调用
2、Java虚拟机需要调用类的main(方法,所以该方法的访问权限必须是public(因为调用的时候java虚
拟机和main方法不在同一个类)
3、java虚拟机执行main方法的时候不必创建对象,所以该方法必须是static
4、main方法接受String类型的数组参数,该数组中保存执行java命令时传递给所执行的类的参数

main方法的注意事项

1.可以直接访问本类的静态成员
2.访问本类的非静态成员,需要先创建对象,再调用即可。

多态

1.多态是面向对象三大特征之一
同一个对象,在不同的时刻表现出来的不同形态

举例子:狗
狗就是狗 狗 dog =new 狗();
我们也可以说 动物 animal=new 狗(;
这里狗在不同的时刻表现出不同的形态,这就是多态。

多态的前提和体现
1.有继承/实现关系;
2.方法重写
3.有父类引用指向子类对象

多态的访问特点

成员变量:编译看左边,执行看左边;
成员方法:编译看左边,执行看右边;
为什么成员变量和成员方法的访问不一样呢?
这是因为成员方法有重写、而成员变量是没有的。

多态的优点和缺点

多态的好处:提高了程序的扩展性
具体体现:定义方法的时候,使用父类型作为参数,将来在使用的时候,使用具体的子类型参与操作
多态的端:不能使用子类的特有功能

public class AnimalParent {
    public void eat() {
        System.out.println("我是AnimalParent 父类中的吃方法");
    }
}

------------------------------------------------------------

public class Cat extends AnimalParent {
    @Override
    public void eat() {
        System.out.println("我是Cat 子类中的吃方法");
    }
}

------------------------------------------------------------

public class Dog extends AnimalParent {
    @Override
    public void eat() {
        System.out.println("我是Dog 子类中的吃方法");
    }
    public void play() {
        System.out.println("我是Dog 子类中的玩方法");
    }
}

------------------------------------------------------------

public class AnimalOperate {
    public void userCat(Cat cat) {
        cat.eat();
    }
    public void userDog(Dog dog) {
        dog.eat();
    }
//---------------------------------------------------------
    public void userAnimal(AnimalParent animal) {
        animal.eat();
    }
}

-----------------------------------------------------------

public class AnimalDemo {
    public static void main(String[] args) {
        AnimalOperate animalOperate = new AnimalOperate();
        animalOperate.userCat(new Cat());
        animalOperate.userDog(new Dog());
//--------------------------------------------------------
        animalOperate.userAnimal(new Cat());
        animalOperate.userAnimal(new Dog());
    }
}

多态中的的转型

1.向上转型(多态机制)
从子到父
父类引用指向子类对象
2.向下转型(强转)
从父到子
父类引用转为子类对象

public class AnimalDemo {
    public static void main(String[] args) {
        AnimalOperate animalOperate = new AnimalOperate();
        animalOperate.userCat(new Cat());
        animalOperate.userDog(new Dog());
//--------------------------------------------------------
        animalOperate.userAnimal(new Cat());
        animalOperate.userAnimal(new Dog());
        AnimalParent animalParent = new Dog();
        Dog dog = (Dog) animalParent;
        dog.play();
    }
}

抽象

在Java中,一个没有方法体的方法应该定义为抽象方法,而类中如果有抽象方法,该类必须定义为抽象类。
抽象类和抽象方法用abstract关键字来修饰
抽象类:abstract class 类名{
抽象方法:pubic abstractvoideatO;//抽象方法中没有方法体

抽象类特点

1.抽象类中不一定有抽象方法,但是有抽象方法的类必须为抽象类;
2.抽象类不能实例化;
3.抽象类由具体的子类进行实例化;
4.子类必须对父类(抽象类)中的所有抽象方法进行重写
5.在抽象类中可以定义非抽象方法
6.子类如果不重写抽象类中的抽象方法,则该类还是为抽象类
7.抽象类中可以有构造方法,用于子类访问父类时的数据初始化;

案例

需求:假如我们在开发一个系统时需要对员工(Employee)类进行设计,员工包含3个属性:姓名、工号(number)以及
工资(salary)。
经理(Manager)也是员工,除了含有员工的属性外,另为还有一个奖金(bonus)属性。
headman (组长)也是员工
然后定义工作的方法.
请使用继承的思想设计出员工类和经理类。

public abstract class EmployeeParent{
  public EmployeeParent(){
    
  }
  public  EmployeeParent(String name,int number,Double salary){
    this.name=name;
    this.number=number;
    this.salary=salary;
  }
  public EmployeeParent(String name,int)
  //员工名称
  private String name;
  //员工的工号
  private int number;
  //员工的工资
  private Double salary;
  /*
  *不用的员工   对应的工作任务  是不一样的  work  抽象方法
  *需要交给我们不同的子类来重写
  */
  public abstract void work();
  
  public String getName(){
    return name;
  }
  public void setName(String name){
    this.name=name;
  }
  public String getNumber(){
    return number;
  }
  public void setNnumber(String number){
    this.number=number;
  }
  public String getSalary(){
    return salary;
  }
  public void setSalary(String salary){
    this.salary=salary;
  }
}

public class Manager extends EmployeeParent{
  private Double bonus;
  
  public Manager(String name,int number,Double salary){
    super(name,number,salary);
    this.bonus=bonus;
  }
  @Override
  public void work(){
    System.out.println("我是项目经理  我负责管理整个项目。。。");
  }
  public Double getBonus(){
   return bonus;
  }
}

public class Headman extends EmployeeParent{
  public Manager(String name,int number,Double salary){
    super(name,number,salary);
  }
  @Override
  public void work(){
    System.out.println("我是项目经理  我负责带领小的团队  编码工作。。。");
  }
}

public class Test{
  public static void main(String[] args){
    EmployeeParent parent = new Manager("siyi",1,20000.00,2000.00);
    parent.work();
    System.out.println("员工的姓名:"+parent.getName());
    System.out.println("员工的编号:"+parent.getNumber());
    System.out.println("员工的薪水:"+parent.getSalary());
    Manager manager=(manager) parent;
    System.out.println("项目经理的奖金:"+manager.bonus());
    System.out.println("----------------------------------");
    Headman headman = new Headman("siyi171",1,20000.00,2000.00);
    headman.work);
    System.out.println("员工的姓名:"+headman .getName());
    System.out.println("员工的编号:"+headman .getNumber());
    System.out.println("员工的薪水:"+headman .getSalary());
  }
}

abstract关键字不能和哪些关键字共存

private 冲突 abstract的方法必须被子类重写,而private不能被继承
final 冲突 final修饰的方法,变量都不能修改,而abstract修饰的方法必须被重写
static 不能共存 无意义static 是静态的,abstract方法中无方法体,无法调用。

接口

接口就是一种公共的规范标准,只要符合规范标准,大家都可以通用。
Java中的接口更多的体现在对行为的抽象!

1.接口 用关键字interface 修饰
public interface 接口名{}

2.类实现接口用implements 表示
public class 类 implements 接口{

3.接口不能够实例化
接口如何实例化呢?参照多态的方式,通过实现类对象实例化,这叫接口多态。
多态的形式:具体类多态,抽象类多态,接口多态。

4.多态的前提:有继承或者实现关系;有方法重写;有父(类/接口引用)指向(子/实现)类对象

5.接口的实现类,要么重写接口中所有的抽象方法、要么是抽象类

public interface Animal{
  public abstract void eat();
}

public class CatImpl implements Animal{
  @Override
  public void eat(){
    System.out.println("我是猫类  我喜欢吃鱼");
  }
}

public abstract class DogImpl implements Animal{
  
}

public class SiyiDogImpl extends DogImpl{
  @Override
  public void eat(){
    
  }
}
/*
*1.有继承(抽象类)/实现(接口)关系
*2.有方法重写
*3.有父(类/接口引用)指向(子/实现)类对象
*/
public class Test{
  public static void main(String[] args){
    Animal animal=new CatImpl();
    animal.eat();
  }
}

接口成员特点

1、成员变量只能是常量;(直接通过接口名称访问即可)
默认修饰符 public static final
2、成员方法只能是抽象方法;
默认修饰符 public abstract
3、接口没有构造方法;
因为接口主要对行为进行抽象,没有具体存在,一个类如果没有父类,默认继承自Object类

public interface Animal{
  public int code1=200;
  //如果使用final修饰的基本数据类型定义好值不能够被修改的
  public final int code2=300;
  //直接通过Animal.属性名称()Animal.code3
  public static final int code3=400;
  
  int code4=500;
  
  //public static final 默认添加
  //在我们的接口中定义的成员方法默认的情况下就是为抽象方法
  public abstract void eat();
  void sleep();
  //在我们的接口中是否可以定义非抽象方法呢?jdk8开始是可以在我们接口中定义非抽象方法
  public default void show(){//非抽象    default void show()
    System.out.println("我们在接口中定义了一个非抽象方法");
  }
}

public class DogImpl implements Animal{
  @Override
  public void eat(){
    System.out.println("我是 猫类  我喜欢吃鱼。。。")
  }
  @Override
  public void sleep(){
    System.out.println("我是 猫类  我喜欢睡觉。。。")
  }
}

public class Test{
//1.在我们接口中定义的  成员变量  都是为  常量
  public static void main(String[] args){
    Animal dog = new DogImpl();
    System.out.println(dog.code1);
    System.out.println(dog.code2);
    System.out.println(dog.code3);
    System.out.println(---------------);
    System.out.println(Animal.code1);
    System.out.println(Animal.code2);
    System.out.println(Animal.code3);
  }
}
案例

猫和狗 (接口版本)

需求:对猫和狗进行训练,他们就可以跳高了,这里加入了跳高功能,请采用抽象类和接口来实现猫和狗的案例。

(1)定义跳高接口(JumpInterface)
成员方法:跳高();—jump();
(2)定义动物类抽象类(Animal)实现跳高接口
成员变量:姓名、年龄;
构造方法:无参、带参
成员方法:get/set方法,吃饭(); —eat();
(3)定义猫类(Cat),继承动物类Animal
构造方法:无参、带参
成员方法:重写eat(),重写跳高jump();
(4)定义狗类(Dog),继承动物类Animal
构造方法:无参、带参3
成员方法:重写eat(),重写跳高jump();

public interface JumpInterface {
    void jump();
}

public abstract class Animal implements JumpInterface {
    private String name;
    private int age;

    public Animal() {
    }

    public Animal(String name, int age) {
        this.name = name;
        this.age = age;
    }

    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 void eat() {
        System.out.println("我是Animal父类,我正在吃");
    }
}

public class Cat extends Animal{
    public Cat() {
    }
    public Cat(String name, int age) {
        super(name, age);
    }
    @Override
    public void eat() {
        System.out.println("我是Cat子类,我正在吃");
    }
    @Override
    public void jump() {
        System.out.println("我是Cat子类,我正在跳");
    }
}

public class Dog extends Animal {
    public Dog() {
    }

    public Dog(String name, int age) {
        super(name, age);
    }

    @Override
    public void eat() {
        System.out.println("我是Dog子类,我正在吃");
    }

    @Override
    public void jump() {
        System.out.println("我是Dog子类,我正在跳");
    }
}

public class Test {
    public static void main(String[] args) {
        JumpInterface dog = new Dog("小白", 3);
        dog.jump();
        Animal dog2= new Dog("小白", 3);
        dog2.eat();

        Animal cat = new Cat("小黑", 2);
        cat.eat();
        cat.jump();

        System.out.println(dog2.getName() + "的年龄是" + dog2.getAge());
        System.out.println(cat.getName() + "的年龄是" + cat.getAge());
    }
}

类和接口的区别

1.类和类的继承关系(一个类只能够单继承一个父类不能够多继承n多个不同的父类)
继承关系,只能单继承,但是可以多层继承
2.类和接口的实现关系(一个类可以实现n多个不同的接口)
实现关系,可以单实现,也可以多实现,还可以在继承一个类的同时实现多个接口
3.接口和接口继承的关系(一个接口是可以继承n多个不同的接口的)
继承关系,可以单继承,也可以多继承

抽象类和接口的区别

1.成员区别
抽象类 变量.常量;有构造方法;有抽象方法,也有非抽象方法
接口常量,抽象方法(JDK8在接口中定义 非抽象方法)
2.关系区别
类与类 继承单继承
类与接口实现,单实现和多实现
接口与接口继承,单继承和多继承
3.设计区别
抽象类 对类抽象,包括属性行为(对事物的抽象)
接口对行为抽象,主要是行为(对行为的抽象)

案例
public abstract class Door {
    private Integer height;
    private Integer width;

    public Door(Integer height, Integer width) {
        this.height = height;
        this.width = width;
    }

    public Integer getHeight() {
        return height;
    }

    public void setHeight(Integer height) {
        this.height = height;
    }

    public Integer getWidth() {
        return width;
    }

    public void setWidth(Integer width) {
        this.width = width;
    }

    public abstract void open();

    public abstract void close();
}

public interface Alarm {
    void alarm();
}

public class PanPanDoor extends Door implements Alarm {

    public PanPanDoor(Integer height, Integer width) {
        super(height, width);
    }

    @Override
    public void open() {
        System.out.println("PanPanDoor is opening");
    }

    @Override
    public void close() {
        System.out.println("PanPanDoor is closing");
    }

    @Override
    public void alarm() {
        System.out.println("PanPanDoor is alarming");
    }
}

public class MeiXinDoor extends Door {


    public MeiXinDoor(Integer height, Integer width) {
        super(height, width);
    }

    @Override
    public void open() {
        System.out.println("MeiXinDoor is opening");
    }

    @Override
    public void close() {
        System.out.println("MeiXinDoor is closing");
    }
}

public class Test {
    public static void main(String[] args) {
        PanPanDoor panPanDoor = new PanPanDoor(200, 100);
        panPanDoor.open();
        panPanDoor.close();
        panPanDoor.alarm();
        System.out.println("PanPanDoor height: " + panPanDoor.getHeight());
        System.out.println("PanPanDoor width: " + panPanDoor.getWidth());

        MeiXinDoor meiXinDoor = new MeiXinDoor(200, 100);
        meiXinDoor.open();
        meiXinDoor.close();
        System.out.println("MeiXinDoor height: " + meiXinDoor.getHeight());
        System.out.println("MeiXinDoor width: " + meiXinDoor.getWidth());
    }
}

JAVA面向对象笔记

https://siyi171.xyz/java-object-oriented-notes/


本文作者
SIYI171


许可协议
CC BY-NC-SA 4.0



暂无评论

发送评论 编辑评论


|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇