面向对象编程

方法的返回值类型:

有返回值:用return返回即可 ,返回的可以是个double,int,也可以是个对象等等

无返回值:一般没有return

注:无返回值的也可以加return,只不过它的后面不能加任何东西。

java变量:

  • 成员变量:在类内方法外的变量,没有static修饰符修饰(堆内存)
  • 类变量:在类内方法外的变量,且有static修饰符修饰(方法区)
  • 局部变量:在方法内或者方法参数列表内的(栈内存)

java变量的默认值:

局部变量没有默认值(没有初始化就使用,会出错),成员变量和类变量都是有默认值的。如下:(注意,string类型属于引用类型的数据)

 java方法:

  • 类方法:类内有static修饰,既可以通过类名访问,也可以通过创建对象去访问。(方法区)
  • 成员方法:类内没有static修饰,只能通过创建对象去访问。(方法区)
  • 构造方法:在创建对象的时候就会启动的方法(方法区)
  • 注:类方法只能调用类方法和类变量,成员方法可以调用类方法、类变量、成员方法和成员变量,构造方法可以调用类方法、成员方法,成员变量和类变量以及其他的构造方法(this关键字去调用)
  • 补充:静态代码块:

  • 方法传参:对于基本数据类型传的是参数的赋值品,也就是说方法对参数的修改不会改变原来的值;对于引用类型传参,传递的是地址,方法对参数的修改会导致原来的值发生改变

 java虚拟机的运算加载的底层逻辑:

  • 方法区:当程序启动的时候,虚拟机首先加载.class字节码文件到方法区。静态的变量和所有的方法也随之加载到方法区(且只加载一次)
  • 栈内存(方法栈):方法运行时使用的内存,比如 main 方法运行,进入方法栈中执行。
  • 堆内存:存储对象或者数组,new 来创建的,都存储在堆内存。

 详解:

  1. 当程序启动的加载时候,首先把.class的字节码文件加载到方法区,包括静态变量和所有的方法(构造,成员,类,mian方法)
  2. 随后,main方法中的变量和方法压到栈里面,从头开始在栈里面执行main方法。
  3. 对于局部变量来说,他们会伴随着他们所属的方法在栈里面而存在消失。
  4. 当new创建对象的时候,首先在堆内存里面开辟一个空间,同时创建对象的成员变量,此时每个成员变量都是默认值,成员方法的指向(地址)方法区的成员方法(并不会在堆内存里面去复写),然后构造方法压到栈中实现对成员变量的赋值。对象的地址指向栈里面的局部变量。
  5. 当要访问某个成员方法的时候,先在堆里面找到这个方法的引用,再找到相应方法区内的字节码,并把字节码加载到栈中执行。执行完后释放相应的内存
  6. 对于类方法,就可以直接再方法区内找到相应的字节码,压到栈中执行就可以了。

this关键字:

继承:

  • 父类的私有变量和私有方法是不能被子类继承的。
  • 子类的所有的构造方法默认调用的是父类的无参构造,但在子类里面可以通过super指定父类的某个构造方法(必须放在子类构造方法的首行)。
  • 构造方法的名字是与类名一致的。所以子类是无法继承父类构造方法的。
  • 子类的构造方法默认调用父类的无参构造
  • 重载:  在同一类中方法名称相同,方法的参数列表不同

  • 重写:子类的访问修饰符必须大于或等于父类的访问修饰符(不能降低访问权限),返回值类型相同或者是父类返回值类型的子类类型,方法名和参数列表相同。

this和super的比较

  • this.成员变量 ‐‐ 本类的
  • super.成员变量 ‐‐ 父类的
  • this.成员方法名() ‐‐ 本类的
  • super.成员方法名() ‐‐ 父类的
  • this(...) ‐‐ 本类的构造方法
  • super(...) ‐‐ 父类的构造方法
public Array(int capacity) {
data = (E[]) new Object[capacity];
//元素个数初始化时默认为0
size = 0;
}
//无参构造函数 容量默认为10
public Array() {
this(10);//调用本类的构造方法
}

 关联:(必须先创建huntdog的对象,避免空指针异常)

  • 关联和继承都可以实现代码的复用
  • 关联的对象可以在成员变量里面,也可以在成员方法及其参数列表里面

     创建关联的时候可以在构造方法内创建huntdog的对象

访问修饰符:

  • 对于方法和变量,四种访问修饰符都可以修饰
  • 对于类,只能用友好型和公共的修饰

代码块:

  • 局部代码块:直接定义在方法内的代码块;
  • 初始化代码块:直接定义在类当中,方法外的代码块;初始化代码块本质上放到构造方法当中执行的,因此每次创建对象的时候,都会执行初始化代码块;(相当于构造器)
  • 静态代码块:在初始化代码块前面加上一个static ,此代码块称为静态代码块。静态代码块在加载字节码时就会自动调用;

子类和父类的加载顺序:

  • 未创建对象前:

  1. 父类–静态变量
  2. 父类–静态初始化块
  3. 子类–静态变量
  4. 子类–静态初始化块
  • 创建对象后:

  1. 父类–变量
  2. 父类–初始化块
  3. 父类–构造器
  4. 子类–变量
  5. 子类–初始化块
  6. 子类–构造器

上传型对象和子类对象调用示意图:

 总结:

  • 上传型对象直接调用的变量都是父类的变量,方法覆盖后的父类的那些方法名字。
  • 子类对象调用的都是覆盖后的变量,方法是覆盖后的全部方法。
  • 隐藏方法和继承方法是站在父类的角度,只能调用父类的方法和变量。
  • 新增的方法和重写的方法是站在子类的角度,不加super时候,调用的是覆盖后的全部方法和变量,对于被隐藏的变量和方法要用super.的形式去调用。
  • 上传型对象的最大好处在于:聚多为一,我们可以用这个“一”去代表“多”,真是运算的时候再向下转型就可以了。
  • 强制类型转换是基本数据类型之间的转换,对于引用类型的转换是向上转型和向下转型。

包装类:

  1. 目的:实现基本数据类型和引用类型的转换;

包装类特有的自动拆箱装箱

package Java后端开发基础.面向对象;

public class day04 {
    //整形和字符串举例:
    public static void main(String[] args) {
//        自动装箱==>转换成引用类型
        Integer a =5;
        System.out.println(a);//自动调b用重写后toString()方法
//        自动拆箱==>转换成基本数据类型
        int b = new Integer(12);
        System.out.println(b);
    }
}

注:当直接让包装类参与基本数据运算的时候,不用通过赋值,也可以自动拆箱

与字符串的转换:

public class day04 {
    //整形和字符串举例:
    public static void main(String[] args) {
        //字符串转基本数据类型
        String a = "12";
        String b = "4";
        //通过对应包装类的类方法
        int c = Integer.parseInt(a);
        //通过包装类的构造器,
        int d = new Integer("b");//自动拆箱
        //基本数据类型转字符串
        //拼接
        String e = ""+c;
        //string的类方法
        String f = String.valueOf(d);
    }
}

toString 方法:

  • 对于每一个对象,打印对象的话,会直接调用其toString 方法

  • Object类的toString 方法:

  • Arrays类的toString 方法:(注意:这个toString 是个静态的,且不是重写了object的,是重载)

  • String类的toString 方法:

 "==" 与 equals 方法:

  • “==”:对于基本数据类型,比较的是值,对于引用类型比较的是地址。
  • equals:只适用于引用类型,比较的也是两者之间的值是否相等。
  • Object的equals 方法:(比较的就是地址)
  • String类重写类equals 方法:(使得string的该方法比较的是字符串的值是否相等)
  • 对于不是字符串的,我们可以就可以用 equals 方法来进行判断,但需要将 equals 方法重写。
  • 上面这个是按照name idcard age写的,三者相同,就会具有相同的哈希值;当如果只写name和age,那么相同的name'和age就拥有相同的哈希值

单例类:

概念:设计一个类只能创建一个实例,则这个类被称为单例类

创建单例类的步骤:
  1. 使用 private 关键字修饰构造器。 (不能在其他类里面创建对象)
  2. 提供一个 public 的 static 的类方法调用构造器。 (唯一的调用唯一类的方式)。
  3. 创建一个 static 的成员变量来保存类对象,同时判断对象是否已经创建。

 两个设计模式:

 总结:创建对象可以在任何地方。

抽象类:

接口:

总结:

  • 抽象类继承,如果子类也是一个抽象类,并不要求一定重写父类方法。如果子类不是抽象类,则要求子类一定要实现父类中的抽象方法。
  • 接口类继承,如果是一个子接口,可以扩展父接口的方法;如果是一个子抽象类,可以部分或全部实现父接口的方法;如果子类不是抽象类,则要求子类一定要实现父接口中定义的所有方法。

接口和类的继承:

接口的继承与类的继承不一样,接口完全支持多继承,即一个接口可以有多个直接父接口,类是单继承关系,子类只能继承一个父类;对于接口的实现,一个类也可以实现多个接口。

final关键字:

 注:对于用final修饰的基本数据类型,赋值后的数值就不能改变了;对于用final修饰的引用类型,它承接的是地址,所以引用类型的值是地址,final修饰后,其地址不会改变,但是,地址里面的东西可以改变(成员变量等等)

System类:(有个计时功能)

 封装:成员变量私有话,每个成员变量提供一对公共的get和set方法;

策略模式:

策略模式:导图:

 工厂模式:

 策略模式和工厂模式结合:

package Java后端开发基础.策略模式和工厂模式;
import java.util.Scanner;
interface Flyable{
    void flying();
}
class fly01 implements Flyable{
    @Override
    public void flying() {
        System.out.println("不会飞");
    }
}
class fly02 implements Flyable{
    @Override
    public void flying() {
        System.out.println("飞的很高");
    }
}
public class Duck {//父类
    protected Flyable flyable;//关联,当成员变量
    public void showfly(){
        flyable.flying();
    }
}
class wildDuck extends Duck{
    public wildDuck(Flyable flyable) {
        this.flyable = flyable;
    }
}
class Rhubarbduck extends Duck{
    public Rhubarbduck(Flyable flyable) {
        this.flyable = flyable;
    }
}
class Flyfactory{
    public static Flyable fa(String s){
        if(s.equals("1")){
            return new fly01();
        }else{
            return new fly02();
        }
    }
}
class test {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        new wildDuck(Flyfactory.fa(scanner.next())).showfly();
        new Rhubarbduck(Flyfactory.fa(scanner.next())).showfly();
    }
}

非静态内部类:

非静态内部类是当作其外部类的成员变量的,无论是在成员方法里面调用还是main方法里面都必须先new,才可以调用

public class test01 {
    private String egg="鸡蛋";
    private cook cook = new cook();//把内部类彻底当成成员变量
    class cook{
        public void cookegg(){
            System.out.println("煮鸡蛋");
        }
    }
    public  void tes(){
        new cook().cookegg();
    }
    public static void main(String[] args) {
        test01 test01 =new test01();
        test01.tes();//通过成员方法调用
        test01.cook.cookegg();//通过调用成员变量用
        test01.new cook().cookegg();//通过new内部类对象调用
    }
}

静态内部类:

在外部类里面当作静态变量用的

public class test01 {
    private String egg="鸡蛋";
    private cook cook = new cook();
    static class cook{
        public void cookegg(){
            System.out.println("煮鸡蛋");
        }
    }
    public void tes(){
        new cook().cookegg();
    }
    public static void main(String[] args) {
        test01 tst = new test01();
        tst.tes();//通过成员方法调用
        tst.cook.cookegg();//通过成员变量调用
        test01.cook cook= new test01.cook();
        cook.cookegg();//通过静态变量调用
    }
}

局部内部类:

匿名内部类:(非抽象子类也可以)

 枚举类:

  •  定义枚举类时不再使用 class 关键字,而是使用 enum 关键字。
  • 主要是为了创建固定个数的对象。
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值