接口
接口的由来:当一个抽象类中 所有的函数都是抽象的时候,那么我们就可以将这个抽象类用另外一种表现形式-接口
在JDK7之前 接口中是不可以定义具体函数的;在JDK8以后 接口中是可以定义具体函数的。(函数必须是静态的函数,成员函数还是依旧默认抽象的)。对于接口而言 里面的函数、变量 所有的接口变量: public static final xxx xxx;所有的函数:public abstract xxx xxx
示例:
//接口A
interface interfaceA{
int age=10; //public static final int age=10;
void show();//public abstract void show();
//函数必须是静态的
public static void haha(){
System.out.println("哈哈");
}
}
各个类或者接口关系
类与类之间是什么关系
单继承 一个类只能且只有一个父类
接口与类之间是什么关系
实现关系
一个类可以实现多个接口 implements
接口与接口之间是什么关系
不可能是实现关系implements
只能是继承关系-多继承
为什么类与类之间不能多继承?为什么接口与接口之间可以多继承?
本质就看 函数是否有函数体!
代码示例:
public class InterfaceDemo01 {
public static void main(String[] args) {
Demo4 d4=new Demo4();
System.out.println(d4.age);
d4.show();
//d4.haha();//调用不到接口的静态函数
interfaceA.haha();//只能通过接口调用静态函数
}
}
interface interfaceA{
int age=10; //public static final int age=10;
void show();//public abstract void show();
//只能是通过接口调用 不会继承给子类
public static void haha(){
System.out.println("哈哈");
}
}
class Demo4 implements interfaceA{
@Override
public void show() {
System.out.println("Demo04 show....");
}
}
interface interfaceB{
void show();
}
interface interfaceC{
void haha();
}
/*
一个类可以多现实多个接口=其实就是相当于继承多个抽象类
本质上还是子类与父类的关系 只不过在接口这里 一个类可以有多个接口爸爸
当一个类想要实现一个接口的时候 有两个选择
1.重写接口中的函数
2.该类定义成抽象即可
*/
//1.重写
class Demo1 implements interfaceB,interfaceC{
@Override
public void haha() {
}
@Override
public void show() {
}
}
//2.定义为抽象的
//The type Demo must implement the inherited abstract method interfaceC.haha()
abstract class Demo2 implements interfaceB,interfaceC{
/*
public abstract void show();
public abstract void haha();
*/
}
//接口与接口多继承
interface interfaceD{
void happyLife(); //你爷爷希望你生活美好
public static void show(){
System.out.println("D show...");
}
}
interface interfaceE{
void happyLife(); //你奶奶希望你生活美好
public static void show(){
System.out.println("F show...");
}
}
//继承到的是属性 抽象函数 但是没有静态函数的继承
interface interfaceF extends interfaceD,interfaceE{
//你爸爸希望你生活美好
}
class Demo3 implements interfaceF{
@Override
public void happyLife() {
}
}
/*
类与类之间不能继承
class DemoA{
void kill(){
System.out.println("Kill B");
}
}
class DemoB{
void kill(){
System.out.println("Kill A");
}
}
class DemoC extends DemoA,DemoB{
}
DemoC dc=new DemoC();
dc.kill();产生了 二义性
*/
接口的作用
1.作为类的一种功能的扩展,这些功能并不是该类原先所具有的功能!
好处:避免了继承带来的一些弊端,只能单继承。
Java当中最常用的三个接口 ,内置的接口:
Comparable 比较接口 给我们的类提供比较的功能
Iterable 可迭代接口 可以将我们该类的对象用于foreach循环
Serializable 序列化接口 我们可以将该对象的数据写出去
对象的数据在内存中 如何将内存中的数据写出去(硬盘 网络)。 想要把内存中的数据提取 就得实现序列化接口。
代码示例:
//第一个作用:在后期对类的功能进行扩展,这些功能并不是该类原先所具有的功能!
//这样子的话 就避免了继承带来的一些弊端 只能单继承
/*
Java当中最常用的三个接口 内置的接口
Comparable 比较接口 给我们的类提供比较的功能
int compareTo(T o); 按照自然顺序进行比较
String.compareTo()
Iterable 可迭代接口 可以将我们该类的对象用于foreach循环
Serializable 序列化接口 我们可以将该对象的数据写出去
对象的数据在内存中 如何将内存中的数据写出去(硬盘 网络)
想要把内存中的数据提取 就得实现序列化接口
*/
public class InterfaceDemo02 {
public static void main(String[] args) {
String s="abc";
}
}
//缉毒 导盲 防爆
interface 缉毒{
void jidu();
}
class Dog implements 缉毒{
@Override
public void jidu() {
System.out.println("可以去缉毒了!");
}
}
class Bird{
void fly(){}
}
interface 飞行{
void fly();
}
class Person implements 飞行{
@Override
public void fly() {
System.out.println("人可以飞了....");
}
}
2.向外提供统一的规范
代码示例:
//第二作用:向外提供统一的规范
//接口的出现 一定程度上对我们的代码设计进行了解耦
//耦合性-两只之间的联系
public class InterfaceDemo03 {
public static void main(String[] args) {
Computer computer=new Computer();
Mouse mouse=new Mouse();
KeyBoard keyBoard=new KeyBoard();
MobileHard mobileHard=new MobileHard();
computer.getUSBConnect(mouse);
computer.getUSBConnect(keyBoard);
computer.getUSBConnect(mobileHard);
}
}
class Computer{
/*
//连接鼠标
public void getMouse(Mouse mouse){}
//连接键盘
public void getKeyBoard(KeyBoard keyBoard){}
//连接移动硬盘
public void getMobilHard(MobileHard mobileHard){}
*/
//连接USB规范对的设备
//USB device=new Mouse();
public void getUSBConnect(USB device){
device.doSomething();
// device.haha();
}
}
interface USB{
void doSomething();
}
class Mouse implements USB{
@Override
public void doSomething() {
System.out.println("鼠标:提供坐标的访问和控制。。。。");
}
void haha(){}
}
class KeyBoard implements USB{
@Override
public void doSomething() {
System.out.println("键盘:提供数据的输入。。。。");
}
}
class MobileHard implements USB{
@Override
public void doSomething() {
System.out.println("移动硬盘:提供外部存储。。。。");
}
}
3.传递代码
代码示例:
//第三个作用:传递代码 和第二个很像
public class InterfaceDemo04 {
public static void main(String[] args) {
Button loginButton=new Button();
Button registButton=new Button();
Button downloadButton=new Button();
//匿名实现子类的匿名对象
//避免了在编译期间所生成的大量备选的类字节码
//在程序运行期间 需要用到了 再去创建实现子类和其对象即可
/*
实现子类的匿名对象 之所以写Mission的原因就在于我们要确定子类是谁的实现子类
new Mission()
匿名实现子类
{
public void doTask() {
System.out.println("登录功能......");
};
}
*/
//了解Android开发-增加知识量 为了毕设
loginButton.doSometing(new /*LoginMission()
class LoginMission implements*/ Mission(){
@Override
public void doTask() {
System.out.println("登录功能......");
}
}
);
registButton.doSometing(new Mission(){
public void doTask() {
System.out.println("注册功能......");
};
}
);
downloadButton.doSometing(new Mission(){
public void doTask() {
System.out.println("下载功能......");
};
});
}
}
//按钮---任务 分开看
interface Mission{
//任务的具体内容
public void doTask();
}
class Button{
//当用户点击该按钮的时候 应该触发的一些事情
//每一个按钮对象的任务不同 此处无法决定具体的代码
public void doSometing(Mission mission){
mission.doTask();
}
}
设计模式:代理模式
代码示例:
//设计模式:代理模式
/*
王宝强-宋喆
王宝强 被代理人
宋喆 代理人
商业演出想要王宝强参演 联系宋喆 由宋喆来安排
但是当时具体去参演的是王宝强
唱歌()
演戏()
综艺()
很明显一点就是 宋 王 都很清楚你们能干啥 知根知底
接口 定义的就是所能够参加商业演出的行为
*/
public class InterfaceDemo05 {
//金主爸爸
public static void main(String[] args) {
宋喆 喆喆=new 宋喆();
喆喆.唱歌();
喆喆.演戏();
喆喆.综艺();
}
}
interface 功能{
void 唱歌();
void 演戏();
void 综艺();
void 男人的功能();
}
class 宋喆 implements 功能{
王宝强 宝宝=new 王宝强();
@Override
public void 唱歌() {
宝宝.唱歌();
男人的功能();
}
@Override
public void 演戏() {
宝宝.演戏();
男人的功能();
}
@Override
public void 综艺() {
宝宝.综艺();
男人的功能();
}
@Override
public void 男人的功能() {
System.out.println("宝强,你去忙吧");
System.out.println("我来向马蓉展现男人的功能");
}
}
class 王宝强 implements 功能{
@Override
public void 唱歌() {
System.out.println("王宝强在唱歌...");
}
@Override
public void 演戏() {
System.out.println("王宝强在演戏...");
}
@Override
public void 综艺() {
System.out.println("王宝强在综艺...");
}
@Override
public void 男人的功能(){
System.out.println("王宝强向马蓉展现男人的功能......");
}
}
内部类
就是当我们在描述一个事物的时候,发现该事物当中又存在另外一个事物的时候,我们把当前的事物称之为外部类 另一个事物称之为内部类。
代码示例:
public class InnerClassDemo {
public static void main(String[] args) {
/*1.如何调用内部类的成员
想要调用内部类的成员 必须先创建内部类的对象 new Inner()
但是直接new Inner()发现找不到Innner这个类
因为Inner是Outter的非静态成员
所以Inner这个类想要存在的前提是创建Outter对象 new Outter()
Outter.Inner inner=new Outter().new Inner();
System.out.println(inner.num);
inner.show();
*/
/*
2.如何区分内部类成员和外部类成员
System.out.println(Outter.this.num+":"+this.num);
*/
/*
3.如何调用内部类的静态成员
静态的东西是优先于对象加载进方法区的
然而haha在一个非静态的类当中,必须先创建Inner对象的haha才存在
这就与我们的第一点冲突了
怎么处理?
如果内部类中有静态 那么内部类必须是静态的
此时就产生一个问题了,内部类当中无法访问外部类的非静态
但是可以访问内部类中的非静态
*/
System.out.println(Outter.Inner.haha);
}
}
class Outter{
int num=10;
int num1=30;
//非静态
static class Inner{
int num=20;
int num2=40;
//静态
static int haha=100;
public void show(){
System.out.println("Inner show......");
//Outter.(这个类的)this.(的对象)num(的num)
// System.out.println(Outter.this.num+":"+this.num);
//Cannot make a static reference to the non-static field num1
// System.out.println(num1+":"+num2);
}
}
}
练习:
public class TransferTest3 {
public static void main(String[] args) {
TransferTest3 test = new TransferTest3();
test.first();
}
public void first() {
int i = 5;
Value v = new Value(); // 对象0x123中 i=15
v.i = 25; // 对象0x123中 i=25
second(v, i); //对象的引用0x123,5
System.out.println(v.i);// 对象0x123中 i=20
}
public void second(Value v, int i) {
//v=0x123
i = 0; //i=0
v.i = 20; //对象0x123中 i=20
Value val = new Value(); //对象0x456 i=15
v = val; //v=0x456
//15+0=15
System.out.println(v.i + " " + i);
}
class Value {
int i = 15;
}
}
/*
15 0
20
*/