Java笔记:面向对象(二)

面向对象

1,包装类

1,定义:为8种基本数据类型分别定义的相应的引用类型。
2,Object是所有类的父类。
3,

基本数据类型包装类
byteByte
shortShort
intInteger
longLong
charCharacter
floatFloat
doubleDouble
booleanBoolean

4,自动装箱和自动拆箱时要注意类型匹配,包装类还可实现基本类型变量和字符串之间的转换:

parseXxx(String s)     除Character之外的所有包装类都提供了该方法  
valueOf(String s)

5,-128-127之间的整数自动装箱成一个Integer实例时,实际上是放入了一个cache的数组中缓存器起来,因此-128-127之间的同一个整数自动装箱成一个实例时,永远是引用cache数组的同一个元素,所以它们全部相等

2,对象的处理

1,打印对象,toString()方法,Java对象都具有toString()方法,Object类提供的toString()方法总是返回该对象实现类的“类名+@+hashcode”,这个返回值并不能实现自我描述功能,一般都会重写toString()方法。
2,测试两个变量相等两种方法:一种利用==运算符,另一种是利用equals()方法,对于两个引用变量时,只有它们指向同一个对象时,才会返回true,一般都会根据需求重写equals()方法。
3,String类里测试两个变量相等除外,它是根据字符串序列来的
4,常量池:包括了关于类、方法、接口中的常量,还包括字符串常量。
5,自反性、对称性、传递性。对任何不是null的x,x.equals(null)一定返回false。

3,类成员

1,定义:以static修饰的成员就是类成员,类成员属于整个类,而不属于单个实例。
2,当系统第一次准备使用该类时,系统会为该类分配内存空间,类变量开始生效,直到该类被卸载。当类初始化后,类变量也被初始化完成。
3,通过对象访问类变量只是一种假象,通过对象访问的依然是该类的类变量,就是可以这样说:系统会在底层转换成该类来访问类变量。
4,对于static关键字而言:类成员不能访问实例成员。
5,单例类:只能创建一个实例,则被称为单实例。把该类的构造器用private隐藏起来,然后再提供个public方法作为该类的访问点用于创建该类的对象,且该方法必须用static修饰(因为调用该方法之前还不存在对象)。例:

public class Singleton {
    private  static Singleton instance;
    private Singleton(){}
    public  static Singleton getInstance()
    {
        if(instance == null)
        {
            instance = new Singleton();
        }
        return instance;
    }
}

4,final修饰符

1,final关键字:final关键字可用于修饰类、变量、方法,用于表示它修饰的类、变量、方法不可变(一旦获得了初始值就不可变)。
2,final成员变量必须由程序员显示初始化,如果final修饰的局部变量在定义时没有指定默认值,则可以在后面代码中对该final变量赋初始值,但只能一次。不能重复赋值,如果final修饰的局部变量在定义时已经指定默认值,则后面代码中不能对该变量进行赋值。
3,当使用final修饰基本类型变量时,不能对基本类型变量进行赋值,因此基本类型变量不能被改变,但对于引用类型变量所引用的地址不会改变,但地址里存储的数据可以改变。
4,final修饰符的一个重要用途就是定义“宏变量”。当定义final变量时就为该变量指定了初始值,而且初始值可以在编译时就确定了下来,那么这个final变量本质上就是一个“宏变量”。如果赋值时是表达式时,被赋的表达式只是基本的运算符或字符串连接运算,没有访问普通变量,调用方法,也会被当成“宏定义”
5,final方法,不希望子类重写父类的某个方法,可以使用final修饰该方法。final类,final修饰的类不可以有子类,
6,不可变类,就是该类创建实例后,该实例的变量是不可变的,不可变类的实例在整个生命周期中永远属于初始化状态,它的实例变量的值不可改变。

5,抽象类

1,抽象方法是只有方法签名,没有方法实现的方法。
2,抽象类必须使用abstract修饰,抽象方法也必须使用abstract修饰,抽象方法不能有方法体;抽象类不能实例化,无法使用new关键字来调用抽象类的构造器创建抽象类的实例;抽象类可以包含成员变量、方法、构造器、初始化块、内部类五种成分。

创建shape抽象类
public abstract class Shape {
    {
        System.out.println("执行Shape的初始化块");
    }
    private String color;
    public abstract double calPerimeter();
    public abstract String getType();
    public Shape(){};
    public Shape(String color){
        System.out.println("执行Shape的构造器");
        this.color = color;
    }
}

3,final修饰的类不能被继承,final修饰的方法不能被重写,因此final和abstract永远不能同时使用。
4,abstract也不能修饰构造器,没有抽象构造器。
5,static和abstract虽然不能同时修饰某个方法,但它们可以同时修饰内部类。
6,抽象类作为多个子类的通用模板,子类在抽象类的基础上进行扩展、改造,但子类总体上会大致保留抽象类的行为方式。

6,接口

1,接口定义的是一种规范,故而不能包含构造器和初始化块定义,可以包含成员变量(只能是静态常量)、方法(只能是抽象实例方法、类方法、默认方法或私有方法)、内部类(包括内部接口、枚举)定义,在接口中定义成员变量时,不管是否使用public static final修饰符,接口里的成员变量总是使用者三个修饰符来修饰,所以接口里的成员变量只能在定义时指定默认值。
2,接口:使用interface关键字,定义语法如下:

[修饰符] interface 接口名 extends 父接口名1,父接口名2...
{
	零到多个常量定义...
	零到多个抽象方法定义...
	零到多个内部类、接口、枚举定义...
	零到多个私有方法、默认方法或类定义方法
} 

3,接口的使用:接口不能用于创建实例,当接口来声明引用类型时,这个引用类型必须引用到其实现类的对象,语法如下:

这个类必须完全实现接口里定义的全部抽象方法
[修饰符] class 类名 extends 父类 implements 接口1,接口2...
{
	类部分体
}

4,接口也可继承,其继承与类相似但接口完全支持多继承。
5,内部类:把内部类隐藏在外部类之内,不允许同一个包中的其他类访问该类,内部类成员可以直接访问外部类的私有数据,但外部类不能访问内部类的实现细节,例如内部类的成员变量,如果外部类需要访问非静态内部类的实例成员,必须显式创建非静态内部类对象来调用访问其实例成员。
6,接口和抽象类的区别:
(1),接口里只能包含抽象方法,静态方法,默认方法和私有方法,不能为普通方法提供方法实现;抽象类则完全可以包含普通方法。
(2),接口里只能包含静态常量,不能定义普通成员变量;抽象类里都可以。
(3),接口里不包含构造器;抽象类里可以包含构造器,抽象类的构造器不是用于创建对象,而是让子类调用这些构造器来完成属于抽象类的初始化操作。
(4),接口里不能包含初始化块;但抽象类则完全可以包含初始化块。
(5),一个类最多只能有一个直接父类,包括抽象类,但一个类可以直接实现多个接口,通过实现多个接口可以弥补Java单继承的不足。

7,内部类

1,内部类:把内部类隐藏在外部类之内,不允许同一个包中的其他类访问该类,内部类成员可以直接访问外部类的私有数据,但外部类不能访问内部类的实现细节,例如内部类的成员变量,如果外部类需要访问非静态内部类的实例成员,必须显式创建非静态内部类对象来调用访问其实例成员。
2,如果希望在外部类以外的地方访问内部类,则内部类不能使用private访问控制权限
(1),省略访问控制符的内部类,只能被与外部类处于同一个包中的其它类所访问。
(2),使用protected修饰的内部类,可被与外部类处于同一个包中的其他类和外部类的子类所访问。
(3),使用public修饰内部类,可以在任何地方被访问。
3,局部内部类,一个内部类被放在方法里定义,仅在该方法里有效。
4,匿名内部类,只需要一次使用的类,匿名内部类必须继承一个父类,或实现一个接口,但最多只能继承一个父类,或实现一个接口。
5,关于匿名内部类的规则:
(1),匿名内部类不是抽象类,系统在创建匿名内部类时,会立即创建匿名内部类的的对象,因此不允许将匿名内部类定义成抽象类。
(2),匿名内部类不能定义构造器,因为匿名内部类没有类名,但匿名内部类可以定义初始化块,可以通过实例初始化块来完成构造器需要完成的事情。
6,定义匿名内部类无需class关键字:

public interface Product {
    double getPrice();
    String getName();
}

public class AnonymousTest {
    public void test(Product p){
        System.out.println("购买了一个" + p.getName() + ",花掉了" + p.getPrice());
    }

    public static void main(String[] args) {
        AnonymousTest ta = new AnonymousTest();
        ta.test(new Product() {
            @Override
            public double getPrice() {
                return 567.8;
            }

            @Override
            public String getName() {
                return "AGP显卡";
            }
        });
    }
}

在这里插入图片描述

8,Lambada表达式

1,Lambada表达式可以完全用于简化创造匿名内部类对象。Lambada表达式的目标类型必须是”函数式接口“,函数式接口代表只包含一个抽象方法的接口。函数式接口可以包含多个默认方法、类方法,但只能声明一个抽象方法。
2,Lambada表达式有如下连哥哥限制:
(1),目标类型必须是明确的函数式接口。
(2),只能为函数式接口创建对象。Lambada表达式只能实现一个方法,因此它只能为只有一个抽象方法的接口(函数式接口)创建对象。
3,为保证目标类型是一个明确的函数式接口:
(1),将Lambada表达式赋值给函数式接口类型的变量。
(2),将Lambada表达式作为函数式接口类型的参数传给某个方法。
(3),使用函数式接口对Lambada表达式进行强制类型转换。
4,方法引用与构造器引用:

(a,b,...)-> 类名.类方法(a,b,...)           引用类方法
(a,b,...)-> 特定对象.实例方法(a,b,...)    引用特定对象的实例方法
(a,b,...)->a.实例方法(b,...)               引用某类对象的实例方法
(a,b,...)->new 类名(a,b,...)              引用构造器
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值