Java初学第三天

1、封装和多态封装

封装,即隐藏对象的属性和实现细节,仅对外公开接口,控制在程序中属性的读和修改访问级别;

将抽象得到的数据和行为(或功能)相结合,形成一个有机的整体,也就是将数据与操作系统的源代码进行有机结合,形成类,其中数据和函数都是类的成员

封装、继承、多态是面向对象的主要特征。

多态

所谓的多态是指一类事物的多种形态,例如,动物--人、老虎、狗等等

父类的数据类型变量指向或者接收其子类对象,例如:Animal animal=new Person();

向上和向下转型

        向上:An imal animal=new Person()

        向下:Animal animal=new Person();Person p=(Person)animal

多态分为两种,一种是运行时多态,另外一种,是编译时多态,是由方法重载所导致的一种多态。我们下面讨论的是运行时多态

在Java中的数据类型划分基本数据类型和引用数据类型。

说一下引用数据类型,当我们的变量的值是一个对象的时候,该变量的值其实是指向了内存空间的,同时该变量也就成为了这段空间的标识。而针对这种类型的变量我们称为引用变量。

Java引用变量同样有两个类型:一个是编译时类型,一个是运行时类型。编译时类型由声明该变量时使用的类型决定,运行时类型由实际赋给该变量的对象决定。

关于多态的定义

多态就是指程序中定义的引用变量所指向的具体类型和通过该引用变量所发出的方法调用在编程时并不确定,而是在程序运行期间才确定,即一个引用变量到底会指向那个类的实例对象,该应用变量发出的方法调用到底是哪个类中实现的方法,必须由程序运行期间才能决定。

同时Java中的多态存在三个前提

  • 要有继承关系(也可以是接口与实现关系)

  • 子类重写父类的方法(编译时的多态)

  • 父类引用指向子类对象(这种情况就会出现编译时和运行时类型不一致)

public class BaseClass {
    public void base() {
        System.out.println("父类的普通方法");
    }
    
    public void test() {
        System.out.println("父类的被覆盖的方法")
    }
}

public class SubClass extends BaseClass {
    @Override
    public void test() {
        System.out.println("子类覆盖父类的方法");
    }
    public void sub() {
        System.out.println("子类的普通方法");
    }
}

public class Demo1 {
    public static void miin(String[] args) {
        //编译时类型和运行时类型完全一样
        BaseClass bc = new BaseClass();
        //编译时类型和运行时类型完全一样,因此不存在多态
        SubClass sc = new SubClass();
        //编译时类型和运行时类型不一样
        BaseClass ploymophi = new SubClass();
    }
}

关键字 instanceof

不同的称呼,有人称为instanceof为运算符,它的前一个操作数通常是一个引用类型的变量,后一个操作数通常是一个类(也可以是接口)。主要用于判断前面的对象是否是后面的类,或者其子类、现实类的实例

其用法如下:

public class Demo1 {
	public static void main(String[] args) {
		Object hello = "Hello";
		if(hello instanceof String){
			System.out.println("字符串是String 的实例")
		}else if (hello instanceof Object) {
            System.out.println("字符串是 Object 的实例")
        }
	}
}

个人理解,该运算符主要是为了避免引用类型在强制转换时出现编译错误。

2、泛型编程

简述

定义:一种把明确类型的工作推迟到创建对象或者调用方法的时候采取明确的特殊的类型

也就是说在泛型使用过程中,操作的数据类型被指定为一个参数,而这种参数类型可以用在类、方法和接口中,分别称为泛型类、泛型方法、泛型接口。

注意:一般在创建对象时,将未知的类型确定具体的类型。当没有指定泛型时,默认类型为Object类型。

泛型还有另外一种称呼我觉得更为容易理解,即参数化类型。简单的说就是将类型由原来的具体的类型参数化,类似于方法中的变量参数,此时类型也定义成参数形式(可以称为类型形参),然后在使用、调用时传入具体的类型(类型实参)。

在Java SE 1.5之前,没有泛型的情况下,通过对类型Object的引用来实现参数的"任意化","任意化"带来的缺点是要做显示的强制类型转换,而这种转化是要求开发者对实际参数类型可以预知的情况下进行的。对于强制类型转换错误的情况,编译器可能不提示错误,在运行的时候才出现异常,这是一个安全隐患。

规则限制

  1. 泛型的类型参数只能是类类型(包括自定义类),不能是简单类型。

  2. 同一种泛型可以对应多个版本(因为参数类型是不确定的),不同版本的泛型类实例是不兼容的。

  3. 泛型的类型参数可以有多个。

  4. 反省的参数类型可以使用extends super 关键字,习惯上称为"有界类型"。

  5. 泛型的参数类型还可以是通配符类型。

public class Cat {
    public String getName(){
        return "小黑";
    }
}

public class Util<T> {
    public T getInstance(T t){
        return t;
    }
}

pulic class Demo1 {
    public static void main(String[] args) {
        //使用泛型
        Util<Cat> util = new Util<>();
        util.getInstance(new Cat()).getName();
        //未使用泛型
        Demo1 demo1 = new Demo1();
        Object ins = demo1.getInstance(new Cat());
        if(ins instanceof Cat){
            Cat Cat=(Cat)ins;
            cat.getName();
        }
    }
    public Object getInstance(Object obj){
        return obj;
    }
}

代码解析

  • 很明显我们在未使用泛型的时候需要进行强制类型转换,同时为了保证安全转换还加上对象的类型判断。试想如果需要判断的类型比较多的时候

  • 在使用泛型之后则可以避免上述问题

泛型边界

设置泛型的时候,实际上是可以任意设置的,只要是类就可以设置。但是在 Java 的泛型中可以指定一个泛型的上限和下限。

泛型的上限,只能接收该类型及其子类,其格式如下

类型名称<? extends 类> 对象名称

泛型的下限,只能接收该类型及其父类型,其格式如下

类型名称<? super 类> 对象名称

  • 15
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ys52IT

你的鼓励将是我创作的最大动力你

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值