Day15知识总结

接口 interface

接口只能定义常量与抽象方法
接口是特殊的抽象类
接口的方法,默认公开抽象[public abstract] 可省略
接口 可以继承[extends]多个接口
“实现”接口 [实现类] implements 实现接口重写抽象方法与继续抽象类
一个子类可实现多个接口 多实现

抽象类与接口区别

抽象类是类class;
具有构造函数,定义常量、成员变量、成员方法即已实现的成员方法与未实现的成员方法[抽象方法];
子类继承抽象类采用关键字extends,一个类只允许继承一个父类;

接口是interface接口;
只有定义常量与抽象方法[即未实现的方法体];
子类实现接口采用implements,一个类允许实现多个接口;
且接口可以使用extends继承多个接口;

接口的简单使用

接口 interface代码

public interface Demo1Fly {//飞
    //int b;接口无成员变量
    //抽象的常量
    public static final int LIFE=100;
    
    //接口的方法 默认公开抽象
    //可省略public abstract
    
    public abstract void fly();
    //可重载
    void fly(String good);//借助于什么力量飞行
}

interface Run{ //跑
    public static final int LIFE=100;
    //接口方法 省略public abstract
    void run();//接口的方法 默认public abstract
}

"实现"接口 implements

继续抽象类 与 实现接口重写抽象方法


//继续抽象
abstract class Person implements Run{
}
//继承
class doctor extends Person{

    @Override
    public void run() {
        System.out.println("医生在跑...");
    }
}

//实现类
class Brid implements Demo1Fly,Run{

    @Override
    public void fly() {
        System.out.println("鸟在天上飞...");
    }

    @Override
    public void fly(String good) {
        System.out.println("鸟在飞借助与"+good);
    }

    @Override
    public void run() {
        System.out.println("鸟有时走路....");
    }
}

调用实现类 main

向上造型

class TestBird{
    public static void main(String[] args) {
        //创建鸟,赋值给鸟类型 调用所有方法
        Brid b1=new Brid();
        b1.fly();
        b1.fly("翅膀");
        b1.run();
        //创建鸟,赋值给Demo1Fly类型 调用所有方法
        Demo1Fly f1=new Brid();
        f1.fly();
        f1.fly("翅膀2");
        //Demo1Fly类型中 没有Run类型的run()方法
        //f1.run();
        //创建鸟,赋值给Run类型 调用所有方法
        Run r1=new Brid();
        //Run类型中 没有Demo1Fly类型的fly()方法
        //r1.fly();
        //r1.fly("翅膀3");
        r1.run();
    }
}

接口继承[extends]多个接口

接口的多继承

//接口,通过extends 实现继承多个接口
interface YunDonYuan extends Run,Demo1Fly{ //运动员
    //继承Run,Demo1Fly接口之后,有三个方法
    void excise();//练习
    void test();//考试
}

实现接口 implements 同时继承extends 类

定义游泳运动员 队员编号 身高 体重 继续People
实现YUNDonYuan接口
创建游泳运动员对象 分别赋值给自己和父类的引用

class People{ //人
    String name;//名字
    char sex;//性别
    String sfZheng;//身份证
}
class PingPangPeople extends People implements YunDonYuan{ //乒乓球运动员
    String id; //队员编号
    double height;//身高
    double weight;//体重
    public void game(){ //比赛
        System.out.println("乒乓运动员比赛....");
    }
    @Override
    public void fly() {
				//空实现
    }

    @Override
    public void fly(String good) {

    }

    @Override
    public void run() {

    }

    @Override
    public void excise() {

    }

    @Override
    public void test() {

    }
}

调用实现类 main

class TestYouYong{
    public static void main(String[] args) {
        YouYongPeople y1=new YouYongPeople();
        //向上造型
        People y2=new YouYongPeople();
        YunDonYuan y3=new YouYongPeople();
        Demo1Fly y4=new YouYongPeople();
        Run y5=new YouYongPeople();
    }
}

@FunctionalInterface 函数式接口

注解:放在方法前 类前面 变量前面 有特殊功能 对类、方法、变量进行一些作用

@FunctionalInterface 函数式接口,只能放在接口前面,且接口内部只能有一个抽象方法

//@FunctionalInterface 函数式接口  只能放在接口前面 接口内部只能有一个抽象方法

@FunctionalInterface  
public interface Demo2Eat {
    void eat();//抽象方法 省略了public abstract
    
//    void eat1();//编译错误
//接口头上有@FunctionalInterface ,接口内部只能有一个抽象方法
}

内部类

一个类定义在另外一个类的内部,在内部的类称内部类外部的类称外部类

内部类 一般private 直接使用外部类的成员方法
内部类 直接使用外部类的成员变量[无关访问权限]
外部类无法调用内部方法与成员变量
内部类不能独立与外部类存在,需先创建外部类再创建内部类
内部类未被创建,则无法调用用其内部类中的方法与属性
功能:类存在的价值仅仅只为某个类服务

public class Demo3Outer {//外部类
    private int x;
    private int y;
    public Demo3Outer(int x,int y){
        this.x=x;
        this.y=y;
    }
    public void print(){
        System.out.println("["+x+","+y+"]");
    }
    class Inner{ //内部类
        public int sum(){
            print();    //内部类 直接使用外部类的成员方法
            return x+y; 
          //内部类 直接使用外部类的成员变量[无关访问权限]
        }
    }
}
class TestInner{
    public static void main(String[] args) {
//        Inner i=new Inner();//内部类不能独立与外部类存在
        Demo3Outer outer=new Demo3Outer(3,6);

        Demo3Outer.Inner inner=outer.new Inner();
        System.out.println(inner.sum());
        //内部类未别创建,则无法使用其内部类中的方法与属性

    }
}

局部内部类

定义在方法中的类,称为局部内部类;局部内部类只能在所在的成员方法中使用
局部内部类,与类一致,可有成员变量与成员方法;
只能在所在的成员方法中被创建,被调用成员方法与成员变量

public class Demo5 {
    public void fun(){
        //局部内部类
        class Inner2{
            int x;
            //局部内部类的方法名可自定义
            public void show(){
                System.out.println("这是局部内部类"+x);
            }
        }
        Inner2 inner2=new Inner2();
        inner2.x=5;
        inner2.show();
    }
    public void show(){
        //Inner2 inner2=new Inner2();
        //编译错误 局部内部类只能用在所在的成员方法中
        //即只能在fun()方法定义的只能在fun()中创建与调用
        System.out.println("这是Demo5的一个成员方法");
    }

    public static void main(String[] args) {
        Demo5 d5=new Demo5();
        d5.fun();
        d5.show();
    }
}

匿名内部类

匿名内部类,在一段程序中需要创建一个类的对象(这个类型需实现某个接口或继承某个抽象类),在对象创建后,这个价值就不存在了,这个类不必命名

匿名内部类[针对于抽象类与接口]
new 类/接口{重写抽象方法}

继承类[包括抽象类] 用 extends
实现接口 用 implements

public class Demo4Timer1 {
    public static void main(String[] args) {
        Timer t=new Timer();
        t.schedule(new TimerTask() {
            //TimerTask是一个抽象类
            //这里使用了匿名内部类
            //重写抽象方法
            @Override
            public void run() {
                System.out.println("该起床了....");
            }
        },1000,5000);
    }
}

利用接口/抽象类创建对象 编译错误

Fly2是接口
Fly2 fly2=new Fly2()
编译错误 接口/抽象类无法创建对象

解决方式

向上造型
[写一个类继承接口/抽象类并重写抽象方法 ]
多次使用

匿名内部类[便于只使用一次]
new 类/接口{重写抽象方法}

interface Fly2{
    void fly();
}
class TestFly2{
    public static void main(String[] args) {
        //Fly2 fly2=new Fly2() //编译错误 接口/抽象类无法创建对象
        //解决方式 向上造型[写一个类继承接口/抽象类并重写抽象方法 多次使用] 匿名内部类[便于只使用一次]
        //匿名内部类
        Fly2 fly1=new Fly2() { //创建一个对象重写抽象方法 匿名的
            @Override
            public void fly() {
                System.out.println("匿名内部类重写,便于只一次创建对象");
            }
        };

        Fly2 fly3=new A();
    }
}
class A implements Fly2{

    @Override
    public void fly() {
        System.out.println("继承继承接口/抽象类并重写抽象方法,多次调用创建对象");
    }
}

匿名函数

静态内部类 static

static修饰的成员内部类称静态内部类,在外部加载时存在
静态内部类随着外部类加载而存在 或 直接new创建对象
静态内类独自有一份存起来 可以通过类名调用静态
静态内部类中 也可以有 非静态方法与非静态成员变量,这部分需要先创建对象才能调用
例如: Demo6.Inner

public class Demo6 {
    int x;
    int y;
    static int m;
    static int n;
    //静态类
    static class Inner{
    //静态内类独自有一份存起来 可以通过类名调用静态
        static int sum=0;
        public void fun(){
//         int sum=x+y; 静态无法用非静态的x,y
            int sum=m+n;
            
            //静态的可在静态类中的非静态方法中使用
            System.out.println("这是雇一个静态内部类,非静态方法");
        }
        public static void print(){
            int sum=m+n;
            //静态的可在静态类中的静态方法中使用
            System.out.println("这是雇一个静态内部类,静态方法");
        }
    }
    public void show(){
        Inner.sum++;
        Inner.print();
        //外部可以使用静态内部类的静态方法与静态变量
        System.out.println("这是一个外部的非静态....");
    }

    public static void main(String[] args) {
        //完整写法 静态内部类随着外部类加载而存在
        静态内部类中的非静态方法,需要先创建类再调用
        Inner inner=new Demo6.Inner();
        inner.fun();
        
        //静态内部类中的静态方法 直接访问
        Demo6.Inner.print();
        
        //Demo6.Inner.fun();  
       // 编译错误
       //fun()是静态内部类的非静态方法 无法直接访问
        
        //直接new创建对象
        new Inner().fun();
    }
}

静态的可以被静态或者非静态的直接使用或调用

但静态的,不能直接调用非静态的,只有先创建对象才能调用非静态的

字符串的常量池与创建对象

new String(); 是创建一个引用对象

直接字符串 是常量池 String str = “a”;

若赋值为常量值

首先到常量池,找是否有该对象 ,找到了就把引用该地址赋值给变量;
找不到此对象,就该常量池创建这个对象,然后把地址赋值为变量

字符串的常量池与创建对象对比

//new String(); 是创建一个引用对象
//直接字符串 是常量池String str = "a";
public class Demo8 {
    public static void main(String[] args) {
        // 字符串对象
        String str = "a"; 
        // str是一个引用你该地址, 指向对象
        String str1 = new String("a"); 
        //  str1是一个引用你该地址, 指向对象。
        String str2 = "a" ;
        //  到常量池,找是否有对象”a“ ;
        //找到了,就把引用该地址赋值给str2
        //找不到,就再常量池创建这个对象
        //最后然后把地址赋值为str2.
        String str3 = new String("a");
         // new , 就创建对象
        // 等号就是再比较对象的引用地址是否相同。
        System.out.println(str == str1); // false
        System.out.println(str == str2); // true
        System.out.println(str == str3); // false
        System.out.println(str1 == str3); // false
    }
}

四个字符串内存结构图

传值和传引用

一个方法参数是8大基本数据类型
该方法不会对实际参数造成影响

一个方法的参数为引用类型
直接修改该参数会对其造成影响
若方法中又创建了新对象,则不会对实际参数有影响

一个方法参数为字符串[引用类型]
该方法赋值一个新字符串,不会对实际参数造成影响

方法参数为8大基本数据类型

 public static void main(String[] args) {
        Demo7 d=new Demo7();

        //一个方法参数是8大基本数据类型,该方法不会对实际参数造成影响
        int x=8;
        int y=9;
        d.p(x,y);
        System.out.println(x+"==="+y);  
        //8===9  未改变值
 }
 public void p(int x,int y){
        x=5;
        y=2;
        System.out.println(x+"==="+y);//5===2
    }

方法参数为引用类型

 public static void main(String[] args) {
        Demo7 d=new Demo7();
 //一个方法的参数为引用类型 直接修改该参数会对其造成影响
        Piont p=new Piont();
        p.x=7;
        p.y=2;
        d.p(p);
        System.out.println(p.x+"==="+ p.y);
        //2===8 值改变
//方法的参数为引用类型 若方法中又创建了新对象 则不会对实际参数有影响
        p.x=3;
        p.y=5;
        d.p2(p);
        System.out.println(p.x+"==="+ p.y);
        //3===5 值未变
 }
 public void p(Piont p){
        p.x=2;  //未有新对象产生 变量指向最初对象
        p.y=8;
        System.out.println(p.x+"==="+p.y);//2===8
    }
    public void p2(Piont p){
        p=new Piont(); 
        //产生了新对象 变量指向新对象
        System.out.println(p.x+"==="+p.y);//0===0
    }
class Piont{
    int x;
    int y;
}

值改变的情况

方法参数为字符串[引用类型]

public static void main(String[] args) {
        Demo7 d=new Demo7();
         //一个方法参数为字符串[引用类型] 该方法赋值一个新字符串 不会对实际参数造成影响
        String strHello = new String("hello");
        d.p(strHello); 
        // 引用传递: fun3函数内部,修改的是局部变量str的引用地址
        System.out.println("strHello:" + strHello);
        //strHello:hello
       
 }
 public void p(String s){
        s= "abcd"; 
// 字符串常量池,把常量池中的"abcd"的引用赋值给str 相当于new了一个对象
        System.out.println("str:" + s);
        //str:abcd
    }

方法参数字符串未变化

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值