1. package包![](https://i-blog.csdnimg.cn/blog_migrate/5fcc3548916fda335b6a8d34a16849f4.png)
package com.itheima.a;
public class Student {
public void eat(){
System.out.println("吃饭睡觉");
}
}
package com.itheima.b;
public class Student {
public void sleep(){
System.out.println("学生睡觉");
}
}
package com.itheima.c;
import com.itheima.a.Student;
public class Test {
public static void main(String[] args) {
Student stu1 = new Student();
stu1.eat();
// 使用全类名创建对象 : 包名 + 类名
com.itheima.b.Student stu2 = new com.itheima.b.Student();
stu2.sleep();
}
}
2. 抽象类
2.1 抽象类的使用
package com.itheima.mabstract;
public class AbstractTest1 {
/*
抽象类: 特殊的父类
问题: 特殊在哪里?
回答: 内部允许编写抽象方法
问题: 什么是抽象方法?
回答: 当我们将共性的方法, 抽取到父类之后, 发现这个方法在父类中无法给出具体明确
而且这个方法, 还是子类必须要有的方法, 就可以设计为抽象方法.
*/
public static void main(String[] args) {
}
}
abstract class Animal {
public abstract void eat();
}
class Cat extends Animal{
@Override
public void eat() {
System.out.println("猫吃鱼");
}
}
class Dog extends Animal{
@Override
public void eat() {
System.out.println("狗吃肉");
}
}
2.2 抽象类的注意事项
package com.itheima.mabstract;
public class AbstractTest2 {
/*
抽象类的注意事项:
1. 抽象类不能实例化(创建对象)
- 如果抽象类允许创建对象, 就可以调用内部没有方法体的, 抽象方法了
2. 抽象类存在构造方法
- 交给子类, 通过super进行访问
3. 抽象类中可以存在普通方法
- 可以让子类继承到继续使用
4. 抽象类的子类
1) 要么重写抽象类中的所有抽象方法
2) 要么是抽象类
*/
public static void main(String[] args) {
Zi z = new Zi();
z.method();
/* Fu f = new Fu();
f.show();*/
}
}
/**
* 4. 抽象类的子类
1) 要么重写抽象类中的所有抽象方法
2) 要么是抽象类
*/
abstract class A{
public abstract void showA();
}
abstract class B extends A{
@Override
public void showA() {
}
public abstract void showB();
}
class C extends B{
@Override
public void showB() {
}
}
abstract class Fu{
public Fu(){
}
public abstract void show();
public void method(){
System.out.println("method...");
}
}
class Zi extends Fu{
public Zi(){
super();
}
@Override
public void show() {
}
}
3. 接口
3.1 接口的介绍
package com.itheima.minterface;
public class InterfaceTest {
/*
接口: 体现的思想就是声明 [规则]
思路: 如果发现一个类, 所有的组成, 都是抽象方法
- 没有成员方法
- 没有普通方法
这种类, 我们通常会设计为Java中的接口, 因为现在这个类存在的唯一价值, 就只是声明规则了
------------------------------------
接口的定义格式:
interface 接口名 {}
注意: 接口不允许实例化
接口和类之间是实现关系, 通过implements关键字来完成
class 类名 implements 接口名{}
实现类(接口的子类):
1. 重写所有抽象方法
2. 将实现类变成抽象类(非常少见, 知道就行)
*/
public static void main(String[] args) {
// 创建实现类对象
InterImpl ii = new InterImpl();
ii.method();
ii.show();
}
}
interface Inter{
public abstract void show();
public abstract void method();
}
// 重写父类所有抽象方法
/**
* 此处InterImpl可以看做接口的子类
*/
class InterImpl implements Inter{
@Override
public void show() {
System.out.println("show...");
}
@Override
public void method() {
System.out.println("method...");
}
}
// 将实现类变成抽象类, 看成认干爹
abstract class InterImpl2 implements Inter{
// 实现对父类(干爹)抽象方法继承
}
class Zi extends InterImpl2{
// 对父类继承来的抽象方法进行重写
@Override
public void show() {
System.out.println("show...");
}
@Override
public void method() {
System.out.println("method...");
}
}
3.2 接口中的成员特点
package com.itheima.minterface;
public class InterfaceTest2 {
/*
接口的成员特点 :
1. 成员变量 : 只能定义常量, 因为系统会默认加入三个关键字
public static final
- 这三个关键字没有顺序关系
2. 成员方法 : 只能是抽象方法, 因为系统会默认加入两个关键字
public abstract
3. 构造方法 : 没有
*/
public static void main(String[] args) {
System.out.println(MyInter.NUM);
}
}
interface MyInter {
public static final int NUM = 10;
public abstract void show();
void method();
}
package com.itheima.minterface;
interface InterA{
void showA();
}
interface InterB{
void showB();
}
interface InterC extends InterA, InterB{
void showC();
}
class InterCImpl implements InterC{
@Override
public void showA() {
}
@Override
public void showB() {
}
@Override
public void showC() {
}
}
public class InterfaceTest3 {
/*
接口和类之间的各种关系 :
1. 类和类之间 : 继承关系, 只支持单继承, 不支持多继承, 但是可以多层继承
2. 类和接口之间 : 实现关系, 可以单实现, 也可以多实现, 甚至可以在继承一个类的同时, 实现多个接口
3. 接口和接口之间: 继承关系, 可以单继承, 也可以多继承
*/
public static void main(String[] args) {
}
}
class Fu{
public void show(){
System.out.println("Fu...show");
}
}
interface A {
void show();
}
interface B {
void show();
}
class Zii extends Fu implements A,B{
}
3.3 抽象类和接口的对比![](https://i-blog.csdnimg.cn/blog_migrate/dc588e0dfae895315928c2553d065736.png)
4. 多态
定义: 同一个行为具有多个不同表现形式或形态的能力
思考问题:
回答问题:
- 不是, 得是父类引用指向子类对象, 或接口类引用指向实现类对象.
- 因为用多态创建完对象, 调用成员方法时, 编译检查父类, 运行时一定会走子类的代码逻辑, 当给不同的子类对象, 走的也就是不同的代码逻辑, 就会有不同的表现形式.
4.1 多态前提
package com.itheima.polymorphism;
public class PolymorphismTest1 {
/*
多态的前提 :
有继承 / 实现关系
有重写方法
有父类引用指向子类对象
1. 对象多态
Animal a1 = new Dog();
Animal a2 = new Cat();
好处: 方法的形参定义为父类类型, 这个方法就可以接收到该父类的任意子类对象了
2. 行为多态
好处: 同一个方法, 具有多种不同表现形式, 或形态的能力
*/
public static void main(String[] args) {
/* // 子类引用指向子类对象
Dog d = new Dog();
// 父类引用指向子类对象
Animal a1 = new Dog();
Animal a2 = new Cat();*/
useAnimal(new Dog());
useAnimal(new Cat());
}
// Animal a = new Dog();
// Animal a = new Cat();
public static void useAnimal(Animal a){
a.eat();
}
}
abstract class Animal {
public abstract void eat();
}
class Dog extends Animal {
@Override
public void eat() {
System.out.println("狗吃肉");
}
}
class Cat extends Animal {
@Override
public void eat() {
System.out.println("猫吃鱼");
}
}
4.2 多态的成员访问特点
package com.itheima.polymorphism;
public class PolymorphismTest2 {
/*
多态的成员访问特点:
1. 成员变量: 编译看左边(父类), 运行也看左边(父类)
2. 成员方法: 编译看左边(父类), 运行看右边(子类)
在编译的时候, 会检查父类中有没有这个方法
没有: 编译出错
有: 编译通过, 但是运行的时候, 一定会执行子类的方法逻辑
原因: 担心你调用的方法, 在父类中是一个抽象方法
----------------------------------------------------------------------------
多态创建对象, 调用静态成员 :
静态的成员, 推荐类名进行调用
细节: 静态的成员, 可以使用对象名调用, 但这是一种假象
- 生成字节码文件后, 会自动将对象名调用, 改成类名调用
*/
public static void main(String[] args) {
Fu f = new Zi();
System.out.println(f.num);
f.show();
f.print(); //Fu.print();
System.out.println("--------------------");
Inter i = new InterImpl();
i.method();
}
}
interface Inter {
void method();
}
class InterImpl implements Inter {
@Override
public void method() {
System.out.println("method...");
}
}
class Fu {
int num = 10;
public void show() {
System.out.println("Fu...show");
}
public static void print() {
System.out.println("Fu...print");
}
}
class Zi extends Fu {
int num = 20;
@Override
public void show() {
System.out.println("Zi...show");
}
public static void print() {
System.out.println("Zi...print");
}
}
4.3 多态中的转型![](https://i-blog.csdnimg.cn/blog_migrate/f42a50c91b6feef2ac5734f8274258bd.png)
注: 向下转型中, 可看做范围大的父类赋值给范围小的子类, 故需要用 (Zi) 来进行强转.
解决办法如下:
4.4 案例-模拟支付接口![](https://i-blog.csdnimg.cn/blog_migrate/8ed0c231821076fe9368fae669f203b6.png)
4.4.1 定义支付方式的接口类
package com.itheima.test;
public interface Payment {
void pay(double money);
}
4.4.2 通过三种支付方式的实现类来实现接口
package com.itheima.test;
public class PlatformPaymentImpl implements Payment {
@Override
public void pay(double money) {
System.out.println("通过支付平台支付了:" + money + "元!");
}
}
package com.itheima.test;
public class BankcardPaymentImpl implements Payment{
@Override
public void pay(double money) {
System.out.println("通过银行卡网银支付了:" + money + "元!");
}
}
package com.itheima.test;
public class CreditCardPaymentImpl implements Payment{
@Override
public void pay(double money) {
System.out.println("通过信用卡快捷支付:" + money + "元!");
}
}
4.4.3 通过测试类来选择支付方式, 测试实现结果
package com.itheima.test;
import java.util.Scanner;
public class Test {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("请选择支付方式: 1. 支付平台支付 2. 银行卡网银支付 3. 信用卡快捷支付");
int choice = sc.nextInt();
Payment payment = null;
switch (choice) {
case 1 :
payment = new PlatformPaymentImpl();
break;
case 2:
payment = new BankcardPaymentImpl();
break;
case 3:
payment = new CreditCardPaymentImpl();
break;
}
System.out.println("请输入您的支付金额: ");
double money = sc.nextDouble();
payment.pay(money);
}
}