一、接口
格式:
- interface {}
接口中的成员的修饰符是固定的:
- 成员常量:public static final
- 成员方法:public abstract
接口中的成员都是public的
接口的出现将“多继承”通过另一种形式体现出来,即“多实现”
接口中的所以方法都必须是抽象的,必须子类实现所有方法,才可以实例化子类,
否则子类仍是抽象类。
interface Inter
{
//因修饰符固定,int num = 3与下等价,编译器会自动补全
public static final int num = 3;
//void show();与下等价,编译器会自动补全
public abstract void show();
}
//子类实现接口。实现的关键字implementsp
class TestInter implements Inter {
public void show() {
System.out.println("implements the Inter");
}
}
public class InerfaceDemo {
public static void main(String[] args) {
TestInter testInter = new TestInter();
System.out.println(testInter.num);
System.out.println(TestInter.num);
System.out.println(Inter.num);
testInter.show();
}
}
一个类可以同时实现多个接口
interface InterA
{
public abstract void showA();
}
//可继承后再实现
class TestManyInter extends TestInter implements Inter,InterA {
public void show(){}
public void showA(){}
}
java在接口与接口之间支持多继承,也仅限于接口与接口之间
interface InterB
{
public abstract void methodB();
}
interface InterC extends InterB
{
public abstract void methodC();
}
二、接口的特点
- 接口是对外暴露的规则
- 接口是程序的功能扩展
- 接口降低程序之间的耦合性
abstract class student{
//在学生类中定义了学生的基本功能,额外的功能不能定义在其中,如抽烟
abstract void study();
void sleep() {
System.out.println("sleep");
}
}
//额外的功能定义成接口,作为功能扩展
interface smoke
{
public abstract void smoke();
}
//演示接口作为功能扩展,实际开发一般不直接定义ZhangSang类
class ZhangSang extends student implements smoke {
void study() {
System.out.println("study java");
}
public void smoke() {
System.out.println("smoke");
}
}
public class TestInterface {
public static void main(String[] args) {
ZhangSang zhangShang = new ZhangSang();
zhangShang.sleep();
zhangShang.study();
zhangShang.smoke();
}
}
三、多态的概念
多态:可以理解为事物存在多种体现形态
动物:猫,狗
猫 x = new 猫();
动物 x = new 猫();
学习多态应从以下四方面入手:
1、多态的体现:
父类的引用指向了自己的子类的引用。
父类的引用也可以接收自己的子类寻象。
2、多态的前提
必须是类与类之间有关系。要么继承,要么实现。
3、多态的好处
提高了程序的扩展性。但也有局限性,就是只能使用父类的引用访问父类的成员。
4、多态的应用
abstract class Animal {
abstract void eat();
}
class Cat extends Animal{
void eat() {
System.out.println("eat fish");
}
void catchMouse() {
System.out.println("catch mouse");
}
}
class Dog extends Animal {
void eat() {
System.out.println("eat bone");
}
void watchHouse() {
System.out.println("watch house");
}
}
public class PolymorphicDemo {
public static void main(String[] args) {
//父类引用指向子类
Animal c = new Cat();
//父类引用接收子类对象
animalEat(c);
animalEat(new Dog());
}
//Animal的所有子类都可以调用此方法,利用了多态的特性,提高了程序的扩展性
static void animalEat(Animal animal) {
animal.eat();
}
}
四、多态间的类型转换有一些事物,有共性却又不同类型,未来可能增多或减少,我们可以采用一种体系来处理
这种情况。这种处理方法:提取共性创建父类,再创建统一操作这些子类的类,未来可能
增多或减少的事物则作子类进行增删。下面是一个培训机构的例子,现在有基础班,高级
班,未来可能开其它类型的班
/*
* 基础班学生:学习、睡觉
* 高级班学生:学习,睡觉
* 将这类事物的共性进行抽取,形成继承体系,
* 再创建一个类对所有子类进行统一操作
*/
abstract class Student {
abstract void study();
void sleep() {
System.out.println("躺着睡");
}
}
//对子类进行统一操作,方便后期进行扩展
class StudentToDo {
void doSome(Student stu) {
stu.study();
stu.sleep();
}
}
//Student的子类,方便统一操作
class BaseStudent extends Student {
void study() {
System.out.println("study base");
}
//覆盖sleep()方法
void sleep() {
System.out.println("任意睡");
}
}
//Student的子类,方便统一操作
class AdvStudent extends Student {
void study() {
System.out.println("study adv");
}
}
public class PolymorphicDemo2 {
public static void main(String[] args) {
StudentToDo stuDo = new StudentToDo();
//只需将student的子类作为参,传入操作子类的的类中的方法,
//即可,方便后期扩展
stuDo.doSome(new BaseStudent());
stuDo.doSome(new AdvStudent());
}
}
五、多态中成员的特点
在多态中成员方法的特点:
在编译时期,参阅引用型变量所属的类中是否有调用的方法。
如果有,编译通过;如果没有,编译失败。
在运行时期,参阅对象所属的类中是否有调用的方法。
简单总结:成员方法在多态调用时,编译看左边,运行看右边。
class Fu {
void method1() {
System.out.println("fu method_1");
}
void method2() {
System.out.println("fu method_2");
}
}
class Zi extends Fu{
void method1() {
System.out.println("zi method_1");
}
void method3() {
System.out.println("zi method_3");
}
}
public class PolymorphicDemo3 {
public static void main(String[] args) {
Fu f = new Zi();
f.method1();
f.method2();
/*f.method3(); 加上这条语句会编译失败,
因为是子类特有方法,编译期间
编译器查找的是引用所属的类 */
}
}
在多态中成员变量的特点:
无论是编译还是运行期间,都参考左边(引用型变量所属的类)
class Fu {
int num = 1;
}
class Zi extends Fu{
int num = 2;
}
public class PolymorphicDemo3 {
public static void main(String[] args) {
Fu f = new Zi();
Zi z = new Zi();
//输出的是父类的成员变量
System.out.println(f.num);
//输出的是子类的成员变量
System.out.println(z.num);
}
}
在多态中静态成员(方法、变量)的特点:
无论是编译还是运行期间,都参考左边(引用型所属的类)
class Fu {
static void method4() {
System.out.println("fu method_4");
}
}
class Zi extends Fu{
static void method4() {
System.out.println("zi method_4");
}
}
public class PolymorphicDemo3 {
public static void main(String[] args) {
Fu f = new Zi();
Zi z = new Zi();
//调用是父类的静态方法
f.method4();
//调用是子类的静态方法
z.method4();
}
}
六、多态中的主板示例
电脑由主板和各种模块(网卡、声卡...),这模块通过PCI接口连接起来,方便符合
PCI接口的各种模块的扩展
/*
* 需求
* 电脑运行
* 电运行基于主板
*/
//PCI接口
interface PCI {
public abstract void open();
public abstract void close();
}
//主板类
class MainBoard {
void run() {
System.out.println("mainBoard run");
}
void usePCI(PCI p) {
if(p != null){
p.open();
p.close();
}
}
}
//符合PCI接口的网卡
class NetCard implements PCI {
public void open() {
System.out.println("NetCard run");
}
public void close() {
System.out.println("NetCard close");
}
}
//符合PCI接口的声卡
class SoundCard implements PCI {
public void open() {
System.out.println("SoundCard run");
}
public void close() {
System.out.println("SoundCard close");
}
}
public class PolymorphicDemo4 {
public static void main (String[] args) {
MainBoard mb = new MainBoard();
mb.run();
mb.usePCI(null);
mb.usePCI(new NetCard());
mb.usePCI(new SoundCard());
}
}
七、多态中的扩展示例
考虑一个需求——我们要通过程序操作数据库。那么,首先,连接数据库,再操作
数据库,关闭数据库连接。连接、操作数据库可以使用JDBC、Hibernate。一开始
我们采用JDBC,后来因某种需求导致我们需要采用Hibernate。我们该如何设计以
降低耦合性、方便功能的修改。数据库的操作就增、删、改、查,我们可以把它定
义成接口。主程序直接使用接口,连接、操作数据库实现接口,即可有效的降低耦
合性。下面伪代码示例:
/*
* 需求:操作数据库
* 数据是:用户信息
* 1、连接数据库,JDBC Hibernate
* 2、操作数据库
* c create r read u update d delete
* 3、关闭数据库连接
*/
interface UserInfoDao {
public abstract void add(User u);
public abstract void delete(User u);
}
public class UserInfoByJDBC implements UserInfoDao {
public void add(User u) {
1、连接数据库,JDBC Hibernate
2、使用SQL语句添加数据
3、关闭数据库连接
}
public void delete(User u) {
1、连接数据库,JDBC Hibernate
2、使用SQL语句删除数据
3、关闭数据库连接
}
}
public class UserInfoByHibernate implements UserInfoDao {
public void add(User u) {
1、连接数据库,JDBC Hibernate
2、使用SQL语句添加数据
3、关闭数据库连接
}
public void delete(User u) {
1、连接数据库,JDBC Hibernate
2、使用SQL语句删除数据
3、关闭数据库连接
}
}
public class DBOperateDemo {
public static void main(String[] args) {
UserInfoDao ui = new UserInfoDao();
ui.add(ui);
ui.delete(ui);
}
}
八、Object类
Object类是根类,是所有其它类的直接或间接父类。这个类里定义了所有类都具备的
功能。
/*
* 演示Object类的使用,重写Objet类
* 的equals和toString方法
*/
class Demo {
int num;
Demo(int num) {
this.num = num;
}
//重写Object类的equals方法
public boolean equals(Object obj) {
if (!(obj instanceof Demo ))
return false;
Demo d = (Demo)obj;
return this.num ==d.num;
}
//重写Object类的toString方法
public String toString() {
//return this.getClass().getName()+ this.num;
return "demo" + num;
}
}
public class ObjectDemo {
public static void main(String[] args) {
Demo d1 = new Demo(2);
Demo d2 = new Demo(3);
Demo d3 = new Demo(2);
System.out.println(d1.equals(d2));
System.out.println(d1.equals(d3));
System.out.println(d1.toString());
}
}