多态
- 多态的形式:
- 父类类型 对象名称 = new 子类构造器;
- 接口 对象名称 = new 实现类构造器;
- 父类类型的范围 > 子类类型范围的。
- 多态的概念:同一个类型的对象,执行同一个行为,在不同的状态下会表现出不同的行为特征。
- 多态的识别技巧:
- 对于方法的调用:编译看左边,运行看右边。
- 对于变量的调用:编译看左边,运行看左边。(多态是针对方法重写的,变量不存在重写,所以看的仍然是父类或接口的变量)
- 多态的使用前提:
- 必须存在继承或者实现关系。
- 必须存在父类类型的变量引用子类类型的对象。
- 需要存在方法重写。
- 多态的优势:
- 在多态形式下,右边对象可以实现组件化切换,业务功能也随之改变,便于扩展和维护。可以实现类与类之间的解耦。
- 实际开发的过程中,父类类型作为方法形式参数,传递子类对象给方法,可以传入一切子类对象进行方法的调用,更能体现出多态的扩展性与便利。
- 多态的劣势:
- 多态形式下,不能直接调用子类特有的功能。编译看左边,父类中没有子类独有的功能,所以代码在编译阶段就直接报错了!
- 引用数据类型的自动类型转换
- 基本数据类型的转换
- 自动类型转换:小范围类型的变量或者值可以直接赋值给大范围类型的变量。
- 强制类型转换:大范围类型的变量或者值必须强制类型转换给小范围类型的变量。
- 引用数据类型的转换
- 引用数据类型转换的思想是一样的:
- 父类类型的范围 > 子类类型的范围。
- Animal Cat
- 自动类型转换(并不能解决多态的劣势):子类类型的对象或者变量可以自动类型转换赋值给父类类型的变量。
- 强制类型转换(解决多态的劣势)
- 语法:父类类型的对象或者变量必须强制类型转换赋值给子类类型的变量。
- 格式:
类型 变量名称 = (类型)(对象或者变量)
- 注意:有继承/实现关系的两个类型就可以进行强制类型转换,编译阶段一定不报错!但是运行阶段可能出现:类型转换异常ClassCastException,Java建议在进行强制类型转换之前先判断变量的真实类型,再强制类型转换。
变量 instanceof 类型
: 判断前面的变量是否是后面的类型或者其子类类型才会返回true。
- 基本数据类型的转换
内部类
-
定义在一个类里面的类就是内部类。
- 外部类 = 宿主
- 内部类 = 寄生
-
作用
- 可以提供更好的封装性,内部类有更多权限修饰符,封装性有更多的控制。
- 可以体现出组件的思想。
-
分类:
- 静态内部类。
- 实例内部类。(成员内部类)
- 局部内部类。
- 匿名内部类。(重点)
-
静态内部类
- 定义:有static修饰,属于外部类本身,会加载一次。
- 成分:类有的成分它都有,静态内部类属于外部类本身,只会加载一次,所以它的特点与外部类是完全一样的,只是位置在别人里面而已。
- 静态内部类访问格式:外部类名称**.**内部类名称
- 静态内部类创建对象的格式:
外部类名称.内部类名称 对象名称 = new 外部类名称.内部类构造器;
- 静态内部类的访问拓展:
- 静态内部类中是否可以直接访问外部类的静态成员?
- 可以的,外部类的静态成员只有一份,可以被共享!
- 静态内部类中是否可以直接访问外部类的实例成员?
- 不可以的**,**外部类的是成员必须用外部类对象访问!
- 静态内部类中是否可以直接访问外部类的静态成员?
-
实例内部类
- 定义:无static修饰的内部类,属于外部类的每个对象的,跟着对象一起加载的。
- 成分特点
- 实例内部类中不能定义静态成员和方法,其他都可以定义。(静态成分只能加载一次,而成员内部类属于对象,会被加载无数次)
- 可以定义常量。
- 访问格式:外部类名称**.**内部类名称。
- 创建对象的格式:
外部类名称.内部类名称 对象名称 = new 外部类构造器.new内部构造器;
- 拓展:
- 实例内部类中是否可以直接访问外部类的静态成员?
- 可以的,外部类的静态成员可以被共享访问!
- 实例内部类中是否可以访问外部类的实例成员?
- 可以的,实例内部类属于外部类对象,可以直接访问当前外部类对象的实例成员!
- 实例内部类中是否可以直接访问外部类的静态成员?
-
局部内部类
- 定义:定义在方法中/构造器中/代码块中/for循环中的内部类就是局部内部类。
- 特点:
- 只能定义实例成员,不能定义静态成员
- 可以定义常量的。
- 小结:局部内部类没啥用。
-
匿名内部类
- 定义:就是一个没有名字的局部内部类。
- 目的:简化代码,也是开发中常用的形式。
- 格式:
new 类名|抽象类|接口(形参){ //方法重写。}
- 特点:
- 匿名内部类是一个没有名字的内部类。
- 匿名内部类一旦写出来,就会立即创建一个匿名内部类的对象返回。
- 匿名内部类的对象的类型相当于是当前new的那个的类型的子类类型。
- 编译后存在.class文件,一般为外部类名$i.class
- 小结:
- 匿名内部类是一个没有名字的内部类。
- 匿名内部类一旦写出来,就会立即创建一个匿名内部类的对象返回。
- 匿名内部类的对象的类型相当于是当前new的那个的类型的子类类型。
包
- 定义:分门别类的管理各种不同的技术。企业的代码必须用包区分。便于管理技术,扩展技术,阅读技术。
- 定义包的格式:
package 包名;
必须放在类名的最上面。 - 包名的命名规范:一般是公司域名的倒写+技术名称。包名建议全部用英文,多个单词用”.“连接,必须是合法标识符,不能用关键字。
- 注意:相同包下的类可以直接访问。不同包下的类必须导包**,**才可以使用!
- 导包格式:*import 包名.类名;
权限修饰符
-
权限修饰符:有四种(private -> 缺省 ->protected - > public),可以修饰成员变量,修饰方法,修饰构造器,内部类,不同修饰符修饰的成员能够被访问的权限将受到限制!
-
四种修饰符的访问权限范围:
-
修饰符 作用域 当前类 同包 子孙类 其他 public √ √ √ √ protected √ √ √ × default(缺省) √ √ × × private √ × × ×
Object类的equals方法
- 包:java.lang.Object,Object类是Java中的祖宗类。一个类要么默认继承了Object类,要么间接继承了Object类。Object类的方法是一切子类都可以直接使用的。
- Object类的常用方法:
- public String toString():
- 默认是返回当前对象在堆内存中的地址信息
- 默认的地址信息格式:类的全限名**@**内存地址,如com.itheima.learn.Student@735b478。
- 直接输出对象名称,默认会调用**toString()方法,所以直接输出对象可以省略toString()**不写。
- 实际开发中直接输出对象,输出对象的地址其实是没有意义的。所以toString方法存在的意义是为了被子类重写。以便能够返回对象的数据内容输出。因为实际开发中我们输出对象更多的时候是希望看到对象的数据内容信息。
- 小结:开发中如果希望输出对象看到对象的内容,只需要重写toString()方法即可。所以toString方法存在的意义是为了被子类重写。
- 默认是返回当前对象在堆内存中的地址信息
- public boolean equals(Object o):
- 默认是比较两个对象的地址是否相同。相同返回**true,**反之。
- 直接比较两个对象的地址是否相同完全可以用**“==”替代equals**。
- 所以equals存在的意义是为了被子类重写,以便程序员可以自己来定制比较规则。
- 小结:equals存在的意义是为了被子类重写,以便程序员可以自己来定制比较规则。
Objects类
- Objects类继承Object类。
- Objects类是从JDK 1.7开始之后才有的。
- Objects的方法:
- public static boolean equals(Object a, Object b)
- 比较两个对象的。
- 底层进行非空判断,从而可以避免空指针异常。更安全!!推荐使用!!
- public static boolean isNull(Object obj) 可直接使用s1 == null
- 判断变量是否为null ,为null返回true ,反之!
- public static boolean equals(Object a, Object b)
Date日期类的使用
- 是面向对象的,会用一个类代表一个事物。
- Date类在Java中代表的是系统当前此刻日期时间对象。
- Date类:
- 包:java.util.Date。
- 构造器:
- – public Date():创建当前系统的此刻日期时间对象。
- – public Date(long time):把时间毫秒值转换成日期对象。
- 方法:-- public long getTime():返回自1970年1月1 日 00:00:00 GMT以来走过的总的毫秒数。
- 时间记录的两种方式:
- a.Date日期对象。
- b.时间毫秒值:从1970-01-01 00:00:00开始走到此刻的总的毫秒值。1s = 1000ms
- 拓展:
- 时间毫秒值的作用:时间毫秒值可以用于做时间的计算:例如代码的执行性能分析。
- (100-89)/1000.0即会显示小数或者(double)(100-89)/1000
DateFormat日期格式化类
- 作用:
- 可以把"日期对象"或者"时间毫秒值"格式化成我们喜欢的时间形式。(格式化时间)
- 可以把字符串的时间形式解析成日期对象。(解析字符串时间)
- DateFormat是一个抽象类,不能直接使用,要找它的子类:SimpleDateFormat
- SimpleDateFormat简单日期格式化类:
- 包:java.text.SimpleDateFormat
- 构造器:public SimpleDateFormat(String pattern):指定时间的格式创建简单日期格式化对象。
- 方法一:
- – public String format(Date date):Date日期对象 -> 格式化成 -> 喜欢的字符串时间形式。
- – public String format(Object time):时间毫秒值 -> 格式化成 -> 喜欢的字符串时间形式。
- 使用
SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss EEE a");
String rs = sdf.format(new Date());
- 或者格式化时间毫秒值
String rs = sdf.format(new Date().getTime());
- 方法二
- – public Date parse(String date) throws ParseException:字符串的时间形式 -> 解析成 -> Date 日期对象。
- 使用:
String date = "2019-11-04 09:30:30";
impleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date newDate = sdf.parse(date);
- 注意:参数必须与被解析的时间的格式完全一致,否则执行报错。
- 拓展:
- yyyy-年,MM-月,dd-日,HH-时,mm-分,ss-秒,EEE-周几,a-上午/下午。
- pattern中除了上述固定字符,可以任意添加别 的字符。如 yyyy-MM-dd HH:mm:ss 或者yyyy年MM月dd日 HH时mm分ss秒。
- (24L * 60 * 60 + 15 * 60 * 60 + 30 * 60 + 29) * 1000 第一个是L,运算结果为long型。
日历类Calendar
- Calendar代表了系统此刻日期对应的日历对象。
- Calendar是一个抽象类,不能直接创建对象。
- Calendar日历类创建日历对象的语法:
Calendar rightNow = Calendar.getInstance();
- Calendar的方法:
- 1.public static Calendar getInstance():返回一个日历类的对象。
- 2.public int get(int field):取日期中的某个字段信息。
- 使用:获取年
int year = rightNow.get(Calendar.YEAR);
- 使用:获取年
- 3.public void set(int field,int value):修改日历的某个字段信息。
- 4.public void add(int field,int amount):为某个字段增加/减少指定的值。
- 5.public final Date getTime():拿到此刻日期对象。
- 6.public long getTimeInMillis():拿到此刻时间毫秒值。
- 7.public final void setTime(Date date):将时间对象转换为日历对象。
ps:b站课程《黑马程序员Java13天进阶》根据官方笔记结合自身情况整理的笔记
视频链接