一、抽象类注意事项
-
问题:
一个类,没有抽象方法,可不可以将这个类定义为抽象类呢? 意义是什么?
可以定位抽象类,意义:就是为了这个类不能够实例化!一般情况:如果一个类中,没由抽象方法,将它定义为抽象类
它的实例化: 可以通过它里面的静态功能,静态功能的返回值类型是当前类本身!
后期:Calendar:日历类 java.util.Calendar;Calendar:抽象类 public static Calendar getInstantce(){ .... .... .... return new GregorianCalendar() ; Calendar的子类 } -
抽象 的关键字:
abstract不能和哪些关键字使用(冲突)abstract可以修饰类,才是这个类不能实例化了,这个类叫抽象类
abstract可以修饰方法----抽象方法:没有方法体
和private关键字不能一块使用:被private修饰的只能在本类中访问,外界类中的成员不能访问!
和static关键字冲突:如果加了静态,子类要重写父类的方法,这种访问方式:
多态:Fu f = new Zi() ;f.方法名() ;
静态的方式—>随着类的加载而加载: 类名.方法名();
和final关键字冲突:被final修饰的方法不能被重写,而abstract抽象方法,要强制子类必须重写,否则子类报错,出现冲突了!abstract:和默认修饰符 abstract 返回值类型 方法名(形参列表) ;和public可以使用
和protected:
限定的是子类: 在同一个包下/或者在不同包下 都可以访问
举例:
abstract class Animal{
//非抽象方法
public void show(){
System.out.println("show Animal");
}
// protected abstract void eat() ;
public abstract void eat() ;
//abstract void eat() ;
//不行的
//private abstract void eat() ; //和private冲突
//public static abstract void eat() ;//和static关键字冲突
// public final abstract void eat() ;//和final关键字冲突
}
class Cat extends Animal{
public void show(){
System.out.println("show Cat");
}
@Override
public void eat() {
}
}
//测试类
public class AbstractDemo {
public static void main(String[] args) {
Animal a = new Cat() ;
a.show();
}
}
二、方法重写注意事项
方法重写的注意事项:
子类继承父类,要重写父类的功能的时候,必须要保证子类的方法的访问权限足够大,要么
就父类的权限保持一致即可!
举例:
//父类
class Fu{
/* public void show(){
System.out.println("show Fu");
}*/
void show(){
System.out.println("show Fu");
}
}
class Zi extends Fu{
//不能够访问
/* void show(){
System.out.println("show Zi");
}*/
public void show() {
System.out.println("show Zi");
}
}
//测试类
public class OverrideDemo {
public static void main(String[] args) {
Fu fu = new Zi() ;
fu.show() ;
}
}
三、接口
-
什么是接口?
接口是比抽象类还抽象的事物,它体现的一种 “扩展性”— 事物的额外功能!
如果一些具体事物能够将额外功能实现了,那么这些具体事物就应该具备这些功能了!
接口:体现的是一种 "like a"的关系
跳高猫—>类似猫 -
定义格式:
interface 接口名{ //接口名要见名知意---符号"标识符的规则" } -
接口中的方法:只能是抽象方法
-
接口特点:不能实例化:不能new
将接口的子类称为"子实现类"
可以是抽象类, 一定会有抽象类的具体的子类,否则没有意义!
也可以是具体类 : 通过具体类实例化接口名 对象名 = new 子实现类名() ;子实现类和接口之间的关系:实现关系 :implements
class 子实现类名 implements 接口名{ }
举例:
//定义一个跳高的接口
interface Jump{
public abstract String jump() ;
}
//猫类
//abstract class Cat implements Jump { //类与接口的关系;实现关系
class Cat implements Jump { //类与接口的关系;实现关系
public void eat(){
System.out.println("猫吃鱼");
}
public void catchMouse(){
System.out.println("猫抓老鼠...");
}
@Override
public String jump() {
return "猫可以跳高了" ;
}
}
//测试类
public class InterfaceDemo {
public static void main(String[] args) {
//Jump jump = new Jump() ;//不能实例化
// Jump jump = new Cat() ; //不能实例化 :Cat是抽象类
//Cat如果是具体类
Jump jump = new Cat() ; ////接口多态: (使用的 最多的) 向上转型
String str = jump.jump();// 使用的 接口(就是一个abstracct)的
System.out.println(str);
// jump.eat() ;
Cat c = (Cat)jump ;//向下转型
c.eat();
c.catchMouse() ;
}
}
四、接口中的成员特点
成员变量:只能是常量:存在默认修饰符:public static final … :可以省略不写
构造方法:无
成员方法:只能是抽象方法:存在默认修饰符:public abstract :可以省略不写
开发中,定义了一个接口
子实现类名都是在接口名的后面加上Impl
举例:
//定义一个接口
interface Inter{
/* public Inter(){
}*/
//成员变量
int num = 100 ;
final int num2 = 200 ;
void show() ;
//public void method(){}
public abstract void method() ;
}
//子实现类
class InterImpl implements Inter{
@Override
public void show() {
System.out.println("show InterImpl");
}
@Override
public void method() {
System.out.println("method InterImpl");
}
}
//测试类
public class InterfaceDemo2 {
public static void main(String[] args) {
//接口多态的形式
Inter i = new InterImpl() ;
System.out.println(i.num);
// i.num = 200 ; //也是常量 :已经被final修饰(没有明确显示)
//i.num2 = 300 ;//num2已经final修饰了
System.out.println(Inter.num); //接口名.变量--->变量: static修饰
System.out.println(Inter.num2);
System.out.println("------------------") ;
i.show();
i.method();
}
}
五、类与类,类与接口,接口与接口的区别(抽象类与接口区别)
-
类与类,类与接口,接口与接口之间的关系
类与类之间:继承的关系 extends :支持单继承,不支持多继承,可以多层继承
类与接口之间:实现关系 implements:
一个类继承另一个类的同时,可以实现多个接口接口与接口之间:继承关系 extends :可以单继承,也可以多继承
interface 接口名1 extends 父接口1,父接口2,…{} -
抽象类和接口的区别?
1)成员的区别成员变量: 抽象类:可以是变量,也可以常量(使用final关键字) 接口:只能是常量:存在默认修饰符:public static final(可以省略不写) 构造方法 抽象类: 有构造方法;无参/有参: 针对父类进行分层初始化 抽象类多态的形式: 抽象的父类名 对象名 = new 子类名() ; 接口:没有构造方法 成员方法: 抽象类:既可以是抽象方法(必须携带abstract),也可以是非抽象方法 接口:只能是抽象方法:存在默认修饰符:public abstract
2)关系的区别
类与类,类与接口,接口与接口之间的关系
类与类之间:继承的关系 extends :支持单继承,不支持多继承,可以多层继承
类与接口之间:实现关系 implements:
一个类继承另一个类的同时,可以实现多个接口
接口与接口之间:继承关系 extends :可以单继承,也可以多继承
interface 接口名1 extends 父接口1,父接口2,...{}
3)设计理念的区别
抽象类----体现的继承关系(类与类之间的关系居多),---描述 "is a"的关系
接口--- 实现关系:一个事物所具备的额外功能,---描述的是一种"like a"的关系
使用接口----使用接口多态---可以提高代码的扩展性!
六、综合问题:
举例1:
package com.qf.test;
class MyClass{
//静态变量
static int a; //随着类的加载而加载:优先于对象进内存 (可以被多个对象共用) 静态区域: 0 100 300
int b; //成员变量 :0 200 mc1
//成员变量:0 400 mc2
}
public class TestMain{
public static void main(String args[]){
MyClass mc1 = new MyClass();
MyClass mc2 = new MyClass(); //新的空间地址
mc1.a = 100;
mc1.b = 200;
mc2.a = 300;
mc2.b = 400;
System.out.println(mc1.a); //300
System.out.println(mc1.b); //200
System.out.println(mc2.a); //300
System.out.println(mc2.b); //400
}
}
举例2:
package com.qf.test;
class A {
public void show() {
show2();
}
public void show2() {
System.out.println("我");
}
}
class B extends A {
/*
* public void show() {
show2();
}
* */
public void show2() {
System.out.println("爱"); //"爱"
}
}
class C extends B {
public void show() {
super.show();
}
public void show2() {
System.out.println("你"); //"你"
}
}
public class Test {
public static void main(String[] args) {
A a = new B(); //多态
a.show();
B b = new C();
b.show();
}
}
举例3:
/* 定义榨汁机JuiceMachine 有榨汁方法makeJuice,传入相应的水果。
如果传入的是Apple 输出 "流出苹果汁"
传入的是Orange 输出 "流出橙汁"
传入的是Banana 输出 "流出香蕉酱"
分析:
有哪些类,这里类中有哪些方法
JuiceMachine 类
makeJuice:榨汁方法 ---->可以定义静态/非静态
makeJuice(Fruit fruit){
fruit.flow() ;
}
Fruit类 :水果类 --> 抽象类
flow() ---->流出 给出声明即可!
Apple
Orange
Banana
继承自水果类 */
//抽象的水果类
public abstract class Fruit {
//流出的方法
public abstract void flow() ;
}
public class Apple extends Fruit {
@Override
public void flow() {
System.out.println("流出苹果汁");
}
}
public class Orange extends Fruit {
@Override
public void flow() {
System.out.println("流出橙汁");
}
}
public class Banana extends Fruit {
@Override
public void flow() {
System.out.println("流出香蕉酱");
}
}
public class JuiceMachine { //看成工厂类
//构造私有化
private JuiceMachine(){}
//静态功能
public static void makeJuice(Fruit fruit){
fruit.flow();
}
//非静态的
//榨汁方法
/* public void makeJuice(Fruit fruit){ //多态
fruit.flow();
}*/
}
public class Test3 {
public static void main(String[] args) {
//创建榨汁机类对象
/*JuiceMachine jm = new JuiceMachine() ;
Fruit fruit = new Apple() ;//父类引用指向子类对象
jm.makeJuice(fruit);
System.out.println("-----------------------");
fruit = new Orange() ;
jm.makeJuice(fruit);
System.out.println("-----------------------");
fruit = new Banana() ;
jm.makeJuice(fruit);*/
Fruit fruit = new Apple() ;
JuiceMachine.makeJuice(fruit);
System.out.println("----------------------") ;
fruit = new Orange() ;
JuiceMachine.makeJuice(fruit);
System.out.println("----------------------") ;
fruit = new Banana() ;
JuiceMachine.makeJuice(fruit);
}
}
举例4:
/**
雇员类(Employee-抽象类):包含抽象方法work()
work()方法表示 工作内容
程序员类和项目经理类都属于雇员
程序员类:属性(姓名、工号、工资),行为(工作:软件开发)
项目经理类:属性(姓名、工号、工资、奖金:经理的特有属性),行为(工作:控制进度)
要求:子类在实现时,用System.out.println()在控制台输出
例如: 程序员 work() 输出:"软件开发"
分析:
程序员,经理: 共有属性:姓名,工号,工资 --->继承自己员工类
经理的特有属性:奖金
Employee-抽象类
姓名,工号,工资
经理和程序员的工作性质不一样,只能员工类给出声明:抽象方法
*/
public abstract class Employee {
//姓名,工号,工资
private String empName ;
private String empId ;
private int empSalary ;
public Employee() {
}
public Employee(String empName, String empId, int empSalary) {
this.empName = empName;
this.empId = empId;
this.empSalary = empSalary;
}
public String getEmpName() {
return empName;
}
public void setEmpName(String empName) {
this.empName = empName;
}
public String getEmpId() {
return empId;
}
public void setEmpId(String empId) {
this.empId = empId;
}
public int getEmpSalary() {
return empSalary;
}
public void setEmpSalary(int empSalary) {
this.empSalary = empSalary;
}
//工作: 抽象方法
public abstract void work() ;
public void show(){
System.out.println("员工的姓名是:"+empName+",工号是:"+empId+"基本工资是:"+empSalary);
}
}
public class Programmer extends Employee {
public Programmer() {
}
public Programmer(String empName, String empId, int empSalary) {
super(empName, empId, empSalary);
}
@Override
public void work() {
System.out.println("程序员日日夜夜敲代码...");
}
}
public class Manager extends Employee {
//特有属性
//奖金
private int bouns ;
public int getBouns() {
return bouns;
}
public void setBouns(int bouns) {
this.bouns = bouns;
}
public Manager() {
}
public Manager(String empName, String empId, int empSalary,int bouns) {
super(empName, empId, empSalary); //先让父类初始化
this.bouns = bouns ;
}
//Employee emp = new Manager() ;
//emp.setBouns() ;//报错
@Override
public void work() {
System.out.println("经理控制进度");
}
}
public class EmployeeTest {
public static void main(String[] args) {
//程序员类:多态
Employee emp = new Programmer() ; //方式1
emp.setEmpName("高圆圆") ;
emp.setEmpId("9527");
emp.setEmpSalary(8000);
emp.show();
emp.work() ;
System.out.println("-------------------------");
//方式2
emp = new Programmer("华安","9527",9000) ;
emp.show();
emp.work() ;
System.out.println("-------------------------");
//测试经理类
emp = new Manager() ;
emp.setEmpName("赵又廷");
emp.setEmpId("9528");
emp.setEmpSalary(5000);
emp.show();
//emp.setBouns() ;
Manager manager = (Manager)emp; //向下转型
manager.setBouns(10000) ;
System.out.println("奖金是"+manager.getBouns());
System.out.println("-------------------------");
Manager m = new Manager() ;
m.setEmpName("张三");
m.setEmpId("it001");
m.setEmpSalary(10000);
m.setBouns(8000);
System.out.println(m.getEmpName()+"---"+m.getEmpId()+"---"+m.getEmpSalary()+"---"+m.getBouns());
System.out.println("-------------------------");
m = new Manager("文章","it002",5000,7000) ;
System.out.println(m.getEmpName()+"---"+m.getEmpId()+"---"+m.getEmpSalary()+"---"+m.getBouns());
}
}
```:
```java
/*举例5:
定义一个动物类,里面有一个方法voice(),
定义一个类Cat,实现voice方法
然后增加一种新的动物类型:Pig(猪),实现voice()方法。
定义一个Dog类,实现voice方法;
定义一个Store(宠物店)类的getInstance方法:
如果传入的参数是字符串dog,则返回一个Dog对象;
如果传入pig,则返回一个Pig对象;否则,返回一个Cat对象。
提示:字符串进行判断 通过equals(字符串)方法
*/
public abstract class Animal {
//里面有一个方法voice(),
public abstract void voice() ;//动物都需要发声
}
public class Cat extends Animal {
@Override
public void voice() {
System.out.println("猫的voice是喵喵喵");
}
}
public class Dog extends Animal {
@Override
public void voice() {
System.out.println("狗的voice汪汪汪");
}
}
public class Pig extends Animal {
@Override
public void voice() {
System.out.println("猪的voice是哼哼哼");
}
}
public class Store {
private Store(){}
//提供getInstance()--->有返回值 静态的功能
public static Animal getInstance(String type){
if(type.equals("dog")){
return new Dog() ;
}else if(type.equals("pig")){
return new Pig() ;
}else{
return new Cat() ;
}
}
}
public class Test3 {
public static void main(String[] args) {
//宠物店调用方法
//多态的间接使用
Animal a = Store.getInstance("dog") ; // Animal a = new Dog() ;
a.voice();
System.out.println("---------------------");
a = Store.getInstance("pig") ;
a.voice();
System.out.println("---------------------");
a = Store.getInstance("monkey") ;
a.voice();
}
}
举例6:
/*
需求:
有运动员和教练,
运动员---篮球运动员和乒乓球运动员,教练---篮球教练和乒乓球教练,
和乒乓球相关的人员为了出国交流,需要学习专业英语,请使用面向对象编程思想设计这个程序!
分析:
乒乓球运动员 和篮球运动员 乒乓球教练和篮球教练
姓名,年龄,性别 姓名,年龄,性别
学习的功能, teach()
抽取 :运动员 抽象类 抽取:教练 抽象类
姓名,年龄,性别 姓名,年龄,性别
特有功能 特有功能
学习:每一种运动员学习不一样,方法声明! teach();
抽取:
人 Person类 抽象
姓名,年龄,性别
eat() ;
乒乓球教练和乒乓球运动员 学习英语 ----> interface StudyEnghlis{}
*/

public abstract class Person {
private String name ;
private int age ;
private String gender ;
public Person() {
}
public Person(String name, int age, String gender) {
this.name = name;
this.age = age;
this.gender = gender;
}
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;
}
public abstract String eat() ;
}
public abstract class Player extends Person {
public Player() {
}
public Player(String name, int age, String gender) {
super(name, age, gender);
}
@Override
public String eat() {
return "运动员吃一些营养餐" ;
}
//定义学的功能
public abstract void study() ;
}
public abstract class Coach extends Person {
public Coach() {
}
public Coach(String name, int age, String gender) {
super(name, age, gender);
}
@Override
public String eat() {
return "教练吃普通的工作餐" ;
}
public abstract void teach() ;
}
public class PingPangPlayer extends Player implements StudyEnglish {
public PingPangPlayer() {
}
public PingPangPlayer(String name, int age, String gender) {
super(name, age, gender);
}
@Override
public void study() {
System.out.println("学习如何接球和发球...");
}
@Override
public void speakEnglish() {
System.out.println("可以使用英语交流...");
}
}
public class PingPangCoach extends Coach implements StudyEnglish {
public PingPangCoach() {
}
public PingPangCoach(String name, int age, String gender) {
super(name, age, gender);
}
@Override
public void teach() {
System.out.println("教授如何接球和发球");
}
@Override
public void speakEnglish() {
System.out.println("可以使用英语交流");
}
}
public class BasketBallPlayer extends Player {
public BasketBallPlayer() {
}
public BasketBallPlayer(String name, int age, String gender) {
super(name, age, gender);
}
@Override
public void study() {
System.out.println("学习如何运球和投篮");
}
}
public class BasketBallCoach extends Coach {
public BasketBallCoach() {
}
public BasketBallCoach(String name, int age, String gender) {
super(name, age, gender);
}
@Override
public void teach() {
System.out.println("教授如何运球和投篮以及战术");
}
}
public interface StudyEnglish {
public abstract void speakEnglish();
}
public class InterfaceTest {
public static void main(String[] args) {
//乒乓球相关的人员的功能比较多a
//测试乒乓球运动员
Player player = new PingPangPlayer() ;
player.setName("张继科");
player.setAge(26);
player.setGender("男");
System.out.println(player.getName()+"---"+player.getAge()+"---"+player.getGender());
String s = player.eat();
System.out.println(s);
player.study();
//接口多态
StudyEnglish se = new PingPangPlayer() ;
se.speakEnglish();
//有参构造方式:自己测试xxxxxxxxxxxxxxx
}
}
本文详细探讨了Java中的抽象类、方法重写、接口及其相关概念。强调了抽象类的主要用途是阻止实例化,并指出抽象方法与private、static、final关键字的冲突。接着阐述了方法重写时需注意的访问权限问题。对于接口,解释了其作为扩展性的体现,以及接口与类、抽象类的区别。此外,总结了接口成员的特性,如只能包含常量和抽象方法。最后讨论了类与类、类与接口、接口与接口之间的关系以及抽象类与接口在设计思想上的差异。


被折叠的 条评论
为什么被折叠?



