面向对象高级

1.类与类之间的访问

  • 同一个包的访问
    • 不需要导包,直接使用即可
  • 不同包下的访问
    • import导包后访问
    • 通过全类名(包名+类名)访问
    • 如com.itn.text.Student stu=new com.itn.text.Student();

包的注意事项

  • package语句必须是程序的第一条可执行的代码
  • package语句在一个java文件只能有一个
  • 如果没有package,默认表示无包名

2.static关键字

static关键字是静态的意思,是java中的修饰符,可以修饰成员方法,成员变量

特点:

        1.被static修饰的成员,会被改类的所有对象所共享

        2.被static修饰的成员,静态随着类的加载而加载,优先于对象存在。

        3.可以通过类名调用

注意事项:

1.静态方法中只能访问静态方法,因为非静态需要创建对象之后才能进行使用

2.非静态方法中,可以使用静态方法,也可以使用非静态成员

3.静态方法中,没用this.关键字,因为一般this需要在创建对象之后才能使用,而静态存在的时候,对象可能还没被创建

3.继承

概述:让类与类之间产生关系(字符类关系),子类可以直接使用父类中的非私有的成员。

继承的格式

  • 格式:public class 子类名 extends 父类名()
  • 范例:public class Zi extends Fu{}
  • Fu:是父类,也称为基类,超类
  • Zi:是子类,也是派生类

优点:

  • 提高了代码的复用性
  • 提高了代码的维护性
  • 让类于类之间产生关系,是多态的前提

缺点

  • 继承是侵入的
  • 降低了代码的灵活性,继承关系导致子类必须拥有父类非私有属性和方法,让子类自由的世界多了一些约束

特点

  • java只支持单继承,不支持多继承,但支持多层继承

继承成员变量访问的特点

在子类中访问一个变量

  • 子类进一步范围找
  • 子类成员范围找
  • 父类成员范围找

注意:如果子父类变量重名,可以通过super关键字区分

super关键字的用法和this关键字的用法相似

this:代表本类对象的引用

super:代表父类存储空间的标识(可以理解为父类对象引用)

访问本类构造方法this()

访问父类构造方法 super()

小知识点

方法重写:在继承体系中,子类出现了和父类一模一样的方法声明(方法名,参数列表,返回值类型)

方法重载:在同一类中,方法名相同,参数列表不同,与返回值无关

方法重写的注意事项

  • 父类中私有方法不能被重写
  • 父类静态方法,子类必须通过静态方法进行重写,父类非静态方法,子类也必须通过静态方法进行重写(静态方法不能被重写,如果子类中,也存在一个方法声明一模一样的方法,可以理解为,子类将父类中同名的方法,隐藏了起来,并非是方法重写)
  • 子类重写父类方法时,访问权限必须大于等于父类

权限修饰符

修饰符同一个类中同一个包中的子类无关不同包的子类不同包的无关类
private
默认
protected
public

 4.构造中构造方法的访问特点

(1)子类中的所有构造方法,都会默认访问父类的无参构造方法

  • 子类在初始化的时候,有可能会使用到父类中的数据,如果父类没用完成初始化,子类无法使用父类的元素,子类初始化前,一定要先完成父类的初始化

怎么完成初始化

构造方法的第一条默认都是:super()

如果没有指定父类会自动继承Object

(2)如果父类没有空参构造方法,只有带参构造方法,会出现什么?

子类通过super,手动调用父类的带参构造方法

this()super()必须放在构造方法的第一行有效语句,并且不能共存

5.抽象类

抽象类的概述:

抽象方法:将共性的行为(方法)抽取到父类之后,发现该方法的实现逻辑无法在父类中给出具体明确,该方法就可以定义抽象方法

抽象类:如果一个类中存在抽象方法,那么改类必须声明为抽象类

注意事项

  • 抽象类不能实例化
  • 抽象类中不一定有抽象方法,有抽象方法的类一定是抽象类
  • 可以有构造函数

6.final关键字

final关键字是最终的意思,可以修饰(方法,变量,类)

final修饰的特点

  • 修饰方法:表明改方法是最终方法,不能被重写
  • 修饰变量:表明该变量是常量,不能再次被赋值,修饰基本数据类型是不能更改,引用数据类型,是地址不能被更改
  • 修饰类:表示该类是最终的类,不能被继承

7.代码块

java中,使用{}括号起来的代码被称为代码块

分类:

  • 局部代码块

        位置:方法中定义

        作用:限定变量的生命周期,及早释放,提高内存利用率

  • 构造代码块

       位置:类中方法定义

        特点:每次构造方法执行的时候,都会执行代码中的代码,并且在构造方法执行前执行

        作用:将多个构造方法中相同的代码,抽取到构造代码中,提高代码复用性

 class szc{

       {

            代码
        }

}
  • 静态代码块

        位置:类中方法定义

        特点:需要通过static关键字修饰,随着类的加载而加载,并且只执行一次

        作用:在类加载的时候做一些数据初始化的操作
        如

 class szc{

        static{

代码

}

}

8.接口

介绍:当一个类中的所有方法都是抽象方法的时候,我们就可以定义其定义为接口,接口也是一种引用数据类型,它比抽象还要抽象

  • 接口存在两个重要意义

        1.规则的定义

        2.程序的扩展性

(1)接口的定义和特点

  • 接口关键字inteface来定义

        public interface 接口名{}

  •        接口不能实例化
  • 接口和类之间是实现关系,通过implements关键字

               public class 类名 impleements 接口名{}

  • 接口的子类(实现类)

        要么重写接口中的所有抽象方法

        要么是抽象类

注意:接口和类的实现关系,可以单实现,也可以多实现

        public class 类名 implements 接口1,接口名2{}

(2)接口成员的特点

  • 成员变量

        只能是常量 系统会默认加三个关键字 public static final

  • 构造方法

        没有构造方法

  • 成员方法

        只能是抽象方法,系统默认加入两个关键字 public abstact(抽象修饰)

   (3)JDK8版中接口成员的特点

        JDK8版本后,java只对接口的成员方法进行了改进

        a.运行在接口中定义非抽象方法,但是需要使用关键字default修饰,这些方法就是默认方法

        作用:解决接口升级的问题

        定义格式: public default 返回值类型 方法名(参数列表){}

        在多继承多个接口的时候,方法名一样,必须对该方法进行重写

        b.接口中允许定义static静态方法

        定义格式:public static 返回值类型 方法名(参数列表){

            }

        接口中静态方法的注意事项

  •   静态方法只能通过接口名调用,不能通过实现类名或者对象调用
  • public可以省略,static不能被省略

        (4)JDK9 增加了一个 private 关键字,修饰方法

(4)类和接口的关系

        

注意:如果直接父类,和接口中出现了相同的方法声明,但是代码逻辑不一样,优先使用直接父类的代码逻辑

接口多继承的时候,方法名一样,必须对该方法进行重写

9.多态

概况:同一对象,在不同时刻表现出来的形态

多态的前提:

1.要有(继承\实现)关系

2.要有方法重写

3.要有父类引用,指向子类对象

(1)多态成员访问特点

构造方法:同继承一样,子类会通过super访问父类构造方法

成员变量:编译看左边(父类),执行看右边(父类)

成员方法:编译看左边(父类),执行看右边(子类)

父类和子类方法相同,变量方法都得有,不然就会编译报错

package jk.test4;



public class duotai {

    public static void main(String[] args) {


        Animal(new Dog());
        Animal(new Cat());
    }
    public static void Animal(Animal a){
        a.eat();
    }

}

abstract class Animal{
    public abstract void eat();
}

class Dog extends Animal{


public void eat(){
    System.out.println("=狗吃ro");
}


}

class Cat extends Animal{


    public void eat(){
        System.out.println("猫吃鱼");
    }
}

(2)多态的好处和坏处

好处:提高了程序的拓展性,定义方法的时候,使用父类用为参数,该方法就可以直接接收到父类的任意子类

坏处:不能使用子类的特有功能,必须是重写父类方法的,父类也有这个方法

(3)转型

向上转型

        从子到父

        父类引用指向子类对象

向下转型

        从父到子

        父类引用转为子类对象

package jk.test4.cs;

public class xs {
    public static void main(String[] args) {
        //1.向上转型
        Fu f=new Zi();
        f.show();
//    不能调用子类特意的成员   f.method;
        //2.向下转型
        Zi z= (Zi) f;
        z.method();
    }
}
class Fu{
    public void show(){
        System.out.println("show");
    }
}
class Zi extends Fu{
    @Override
    public void show() {
        System.out.println("Zi show");
    }

    public void method(){
        System.out.println("我是子类特有的方法,method");
    }

}

(4)转型的风险

如果被转的引用类型变量,对应的实际类型和目标类型不是同一种类型,那么转型的时候就会出现 ClassCastExption

解决方法如下

关键字:instanceof

格式:变量名 instanceof 类型  判断关键字左边的变量,是否是右边的类型,返回boolean类型结果

先判断再转

10.内部类

概述:就是在一个类中定义一个类, 举例:在一个A类的内部定义一个B类,B类就被称为内部类

在类的成员位置就是:成员内部类

在类的局部位置就是:就是局部内部类

成员内部类

内部类访问特点:内部类可以直接访问外部类的成员,包括私有

                                外部类想访问内部类,必须创建对象

外部类名.内部类名 对象名=new 外部类对象().new 内部类对象()

package jk.test5;

public class nbl {
    public static void main(String[] args) {

        /*
        *       创建内部类对象的格式
        * 外部类名.内部类名 对象名=new 外部类对象().new 内部类对象()
        * */
        Outer.Inner i=new Outer().new Inner();
        System.out.println(i.num);
        i.show();
    }
}
class Outer{
     private  int a=10;
    class Inner{
        int num=10;
        public void show(){
            System.out.println("Inner..show");
            /*
            * 内部类访问外部类成员,可以直接访问,包括私有
            * */
            System.out.println(a);
        }
    }
}

成员内部类,也属于(成员),既然是成员就可以被一些修饰符所修饰

private

        私有成员内部类访问:在自己所在的外部类中创建对象访问

static

        静态成员内部类访问格式:外部类名.内部类名 对象名=new 外部类名.内部类名()

        静态成员内部类的静态方法:外部类名.内部类名.方法名();

局部内部类

局部内部类是在方法中定义的类,所以外界是无法直接使用,需要方法内部创建对象并使用该类可以直接访问外部类的成员,也可以访问内的局部变量

package duotai;

public class test1 {

    public static void main(String[] args) {
        Outer i=new Outer();
        i.method();

    }
}

class Outer{
    public  void  method(){
    class Inner{
        public void show(){
            System.out.println("show....");
        }
    }
        Inner i=new Inner();
    i.show();

    }
}

匿名内部类

概述:匿名内部类本质上是一个特殊的局部内部类(定义在方法内部)

前提:需要存在一个接口或类

格式:new类名或者接口名(){

        重写方法       

                }

理解:将继承\实现,方法重写,创建对象,放在了一步进行。

10Lambda表达式的标准格式

匿名内部类中重写swim()方法的代码分析

  • 方法形式参数为空,说明调用方法不需要传递参数
  • 方法返回类型为void,说明方法执行没有结果返回
  • 方法体中的内容,是我们具体要做的事情

        

go(new Outer() {
        @Override
        public void show() {
            System.out.println("我们去游泳吧");
        }
    });
}

Lambda表达式的代码分析

  • ():里面没有内容,可以看成是方法形式参数为空
  • ->:箭头指向后面要做的事情
  • {}:包括一段代码,我们称为代码块,可以看成是方法体的内容
  • 格式:(形式参数)->{代码块}
  • 形式参数:如果有多个参数,参数之间用逗号隔开;如果没有参数,留空即可
go(()->{
    System.out.println("去玩");
});

组成Lambda表达式3要素:形式参数,箭头,代码块

使用Lambda表达式的使用前提

  • 有一个接口
  • 接口中有且仅存有一个抽象方法
package duotai;

public class test1 {



    public static void main(String[] args) {




        go(()->{
            System.out.println("去玩");
        });
    }
    public static void go(Outer sw){
        sw.show();

    }
}

interface Outer{
     public void show();


 }

lambda表达式的省略模式

省略规则:

  • 参数类型可以省略,但是有多个参数的情况下,不能只省略一个
  • 如果参数有且仅有一个,那么小括号可以省略
  • 如果代码块的语句只有一条,可以省略大小括号和分好,甚至是return

lambda表达式和匿名内部类的区别

所属类型不同

  • 匿名内部类:可以是接口,也可以是抽象类,还可以是具体类
  • lambda表达式:只能是接口

使用限制不同

  • 如果接口有仅有一个抽象方法,可以使用lambda表达式,也可以使用匿名内部类
  • 如果接口中多于一个抽象方法,只能使用匿名内部类,而不能使用lambda表达式

实现原理不同

  • 匿名内部类:编译之后,产生一个单独的.class字节码文件
  • Lambda表达式:编译之后没有一个单独的.class字节码文件。对呀的字节码会在运行的时候动态生成
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值