Java菜鸟之路3

2020.5.15 今天收到了第一份互联网行业的offer,因为疫情的原因,不得不取消了。电话面试的过程十分曲折,革命尚未成功,还需努力

多态

多态性是允许你将父对象设置成为一个或更多的他的子对象相等的技术。

  今天的第一个知识点是Java的特性之一,多态。我们首先来看一下官方如何看待多态:接口的多种不同的实现方式即为多态

多态的使用

父类对象 对象名 = new 子类对象();
接口名称 对象名 = new 实现类名称();

对象的向上转型
  对象的向上转型就是多态的写法,创建一个子类对象,当成父类来看待使用

父类对象 对象名 = new 子类对象();

注意:向上转型一定是安全的,举例:猫可以被看做动物来看待
弊端:不能使用子类区别于父类的方法

对象的向下转型
  对象的向下转型其实是还原的过程,举例:将本来被看做动物的猫重新当作猫本身来看待,其实就是进行强制类型转换,将父类还原为原本的子类

子类名称 对象名 = (子类名称)原本父类对象;

  这里带大家认识一个新的运行期异常:ClassCastException:当发生向下转型时,如果对象本身不是这个类,但又进行了强转,就会法僧类转换异常。当然这个异常时可以避免的,方法就是使用instanceof 关键字

	if(dog.instanceof 2Ha){
	2Ha 2ha = (2Ha)dog;
}

  用这种方法,在转型前进行判断,避免类转换异常的产生,需要熟练掌握
多态成员访问的特点(比较枯燥,但是需要记忆)

Parent p = new Child();

成员变量:
编译看左边(基类),运行看左边(基类)
成员方法:
编译看左边,运行看右边
静态方法:
编译看左边,运行看左边

内部类

  在Day1中讲类的命名时,我们注意到可以使用$字符,但是我们不推荐主动使用,接下来的内部类中,他就会和我们见面了

  内部类顾名思义,就是定义在类内部的类在,《Think in java》中有这样一句话:
  “使用内部类最吸引人的原因是:每个内部类都能独立地继承一个(接口的)实现,所以无论外围类是否已经继承了某个(接口的)实现,对于内部类都没有影响。
  借用他人的一句话,接口是Java无法多继承的解决方案,而内部类,让这个解决方案更加完善
内部类的特性(摘自书中)
  1、内部类可以用多个实例,每个实例都有自己的状态信息,并且与其他外围对象的信息相互独立
  2、在单个外围类中,可以让多个内部类以不同的方式实现同一个接口,或者继承同一个类。
  3、创建内部类对象的时刻并不依赖于外围类对象的创建。
  4、与继承不同,内部类并没有令人迷惑的“is-a”关系,他就是一个独立的实体。
  5、内部类提供了更好的封装,除了该外围类,其他类都不能访问。

成员内部类
使用方式:
1、间接
在外部类的方法中调用内部类的方法,main只调用外部类的方法
2、直接

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

当时在学习HashMap的遍历时,Map.entrySet其实就是一个内部类

还有一个问题值得我们思考,内部类中的变量重名问题,下面是规则:
1、内部类的局部变量 直接使用
2、内部类的成员变量 this.变量名
3、外部类的成员变量 外部类.this.变量名

局部内部类
  如果一个类定义在方法内,被成为局部内部类,他只属于这个方法,超出方法就不能使用
  局部内部类想要访问所在方法的局部变量,该局部变量必须是final的

匿名内部类
  如果接口的实现类,或父类的子类只需要使用唯一的一次,这样的情况下就可以使用匿名内部类
  匿名内部类的用法过于广泛,尽管它的语法复杂,但是可以简化我们的代码,所以掌握匿名内部类是十分有必要的

new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("匿名内部类的使用");
            }
        }).start();

Object类

类 Object 是类层次结构的根类。每个类都使用 Object 作为超类。所有对象(包括数组)都实现这个类的方法。

protected  Object clone() //创建并返回此对象的一个副本。 

  想要使用clone方法,就需要实现Cloneable接口,值得注意的是java.lang.Object类中的clone()是浅拷贝

int hashCode() //返回该对象的哈希码值。 

1、HashCode的存在主要是用于查找的快捷性,如Hashtable,HashMap等,HashCode经常用于确定对象的存储地址;

2、如果两个对象相同, equals方法一定返回true,并且这两个对象的HashCode一定相同;

3、两个对象的HashCode相同,并不一定表示两个对象就相同,即equals()不一定为true,只能够说明这两个对象在一个散列存储结构中。举个路人皆知的例子:
  "通话"和"重地"的hashcode相同

4、如果对象的equals方法被重写,那么对象的HashCode也尽量重写。

String toString() //返回该对象的字符串表示。 

  toString方法是所有类都有方法,显然Java开发者是想要字符串的操作更方便些。
  它会返回该对象的字符串表示。通常,toString 方法会返回一个“以文本方式表示”此对象的字符串。结果应是一个简明但易于读懂的信息表达式。建议所有子类都重写此方法。

void wait() //在其他线程调用此对象的 notify() 方法或 notifyAll() 方法前,导致当前线程等待。 
void notify() //唤醒在此对象监视器上等待的单个线程。 
void notifyAll() //唤醒在此对象监视器上等待的所有线程。 

这三个方法与多线程相关,并且都是final的,无法被重写!

先讲nofity方法:
   nofity方法会唤醒在此对象监视器上等待的单个线程。如果所有线程都在此对象上等待,则会选择唤醒其中一个线程。选择是任意性的,并在对实现做出决定时发生。线程通过调用其中一个 wait 方法,在对象的监视器上等待。

nofifyAll方法:
  nofityAll唤醒在此对象监视器上等待的所有线程。

wait方法:
  wait方法使当前线程阻塞,前提是 必须先获得锁,一般配合synchronized关键字使用

boolean equals(Object obj) 
          //指示其他某个对象是否与此对象“相等”。 

  在之前的学习中已经学习过Object类的equals方法了,这里不再赘述

StringBuilder和StringBuffer

  面试的时候经常被提问到一个问题,StringBuilder和StringBuffer两个类有什么区别,人人都知道StringBuilder是线程不安全的,StringBuffer是线程安全的。我们来进一步学习。

  查看API文档,官方对StringBuilder是这么描述的:

首先,一个可变的字符序列。此类提供一个与 StringBuffer 兼容的 API,但不保证同步。该类被设计用作 StringBuffer 的一个简易替换,用在字符串缓冲区被单个线程使用的时候(这种情况很普遍)。如果可能,建议优先采用该类,因为在大多数实现中,它比 StringBuffer 要快。

  因此,单线程下字符串的大量操作可以使用StringBuilder,它的速度更快。

When it rains,look for rainbows.When it’s dark,look for stars.

  • 1
    点赞
  • 0
    评论
  • 0
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

©️2021 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值