来到这一章,说明你已经经过前面的新手村了(JAVA基础知识笔记),接下来的将会遇到些神秘莫测的妖魔鬼怪—-抽象怪。在前面的章节算是知道Java的一些浅浅的基本规则,懂得他的格式语法,学习到他的代码处理逻辑,例如,掌握基础语法、数据类型、控制结构(如 if
、for
)、类和对象等概念。伴随学习的过程中,偶尔会刷新出一些小怪(练习题)来热身找找手感。面向对象编程有四大原则:封装(隐藏内部细节,提供接口)、继承(子类复用父类属性和方法)、多态(同一操作在不同对象上有不同表现)和抽象(定义通用行为,隐藏具体实现)。接下来就开始这段新的征程吧。
面向对象的概述
什么是对象
万物皆对象,客观存在的事物都是对象,大到名胜古迹,小到剪刀、钟表、信封等
什么是类
类是对现实生活中一类具有共同属性和行为的事物的抽象
类是对象的数据类型,类是具有相同属性和行为的一组对象的集合
简单理解:类就是对现实事物的一种描述
什么是对象属性
属性:对象具有的各种特征,每个对象的每个属性都拥有特定的值。
什么是对象的行为
行为对象能够执行的操作
类和对象的关系
类:类是对现实生活中一类具有共同属性和行为的事物的抽象
对象:是能够看得到摸的着的真实存在的实体
简单理解:类是对事物的一种描述,对象则为具体存在的事物
类是对象的抽象,对象是类的实体
类的定义
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:代表父类存储空间的标识(可以理解为父类对象的引用)
关键字 | 访问成员变量 | 访问构造方法 | 访问成员方法 |
this | this.成员变量(访问本类的成员变量) | this(..)(访问本类的构造方法) | this.成员方法()(访问本类的成员 方法) |
super | super.成员变量(访问父类的成员变量) | 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());
}
}