包
什么是包?
-
包是用来分门别类的管理各种不同类的,类似于文件夹、建包利于程序的管理和维护。
-
包装语法格式:package 公司域名倒写.技术名称。注册建议所有英文小写,具有意义。
package com.itheima.javabean; public class Student { }
-
建包语句必须在第一行,一般IDEA有助于创建工具
导包
-
可直接访问相同包下的类,不同包下的类必须导包才能使用!导包格式:import 包名.类名;
-
如果一个类别需要不同的类别,而这两个类别的名称是相同的,那么默认情况下只能导入一个类别,另一个类别需要带包名访问。
权限修饰符
权限修饰符是什么?
-
权限修饰符:用于控制成员可访问的范围。
-
可以修饰,修访问不同权限修饰符的成员的范围将受到限制。
权限修饰符的分类及具体作用范围:
-
权限修饰符:由小到大有四种作用(private -> 缺省 -> protected - > public )
正在上传…重新上传取消
完成权限修饰符需要具备以下能力
-
能够识别人定义的成员的访问权限。
-
自定义成员(方法、成员变量、构造器等)一般满足以下要求:
-
成员变量一般是私有的。
b. 该方法通常是公开的。
c. 如果成员只想使用这种访问,private修饰。
d. 如果该成员只想访问同一包下的其他类别和子类,则使用该类别protected修饰。
-
final
final的作用
final 关键词是最终的意思,
修饰方法:表明该方法是最终方法,不能重写。
修改变量:表示变量第一次赋值后,不能再次赋值(
修饰:说明这类是最终类,不能继承。
final注意修改变量
-
final修饰的变量是:然后存储变量**数据值**不能发生改变。
-
final修饰的变量是:变量存储的地址值不能改变,但地址指向的对象内容可以改变。
常量
常量概述和基本功能
常量
-
使用常量public static final修改后的成员变量必须具有初始值,其值在执行过程中不能改变。
-
常量的功能和好处:可用于制作系统配置信息,方便程序维护,提高可读性。
public class Constant { public static final String SCHOOL_NAME = “传智教育"; public static final String LOGIN_NAME = “admin"; public static final String PASS_WORD = “123456"; }
常量执行原理
-
在编译阶段会进行“宏替换”,把使用常量的地方全部替换成真实的字面量。
-
这样做的好处是使用常量程序的执行性能与直接使用字面量相同。
常量信息标志和分类
为了控制玛丽移动的方向,现在开发的超级玛丽游戏需要接收用户输入的四个方向的信号。
信息标志和分类选择常量: 实现软编码形式的代码可读性好。
枚举
枚举的概述
枚举的概述
-
枚举是Java特殊类型之一
-
枚举的作用:"做信息标志和信息分类"。
定义枚举类格式:
修饰符 enum 枚举名称{ 第一行是列举枚举实例的名称。 }
enum Season{ SPRING , SUMMER , AUTUMN , WINTER; }
枚举的特征
-
枚举类都继承了枚举类型:java.lang.Enum
-
枚举是最后一类,不能继承。
-
构造器是私有的,枚举不能创建对象。
-
默认情况下,枚举类的第一行列出了枚举对象的名称。
-
枚举类相当于多种模式。
-
使用场景演示枚举
案例说明: 为了控制玛丽移动的方向,现在开发的超级玛丽游戏需要接收用户输入的四个方向的信号。
信息标志和分类选择常量: 虽然可以实现可读性,但参数不受限制,代码相对不够严格。
枚举作为信息标志和分类: 最好的信息分类技术是代码可读性好,入参约束严谨,代码优雅!推荐使用!
抽象类
抽象类概述
-在Java中abstract这意味着抽象。如果一个类别中某种方法的具体实现不能确定,则可以声明为abstract修饰抽象方法(不能写方法体),这一类必须使用abstract修饰,叫抽象类。
public abstract class Animal{ public abstract void run(); }
抽象使用总结和注意事项
-
抽象类可以理解为被子类继承的不完整设计图。
-
,否则,这一类也必须定义为抽象类。
总结
1.抽象的作用是什么? 它可以被子类继承,作为模板,也可以改进代码重用。 2.抽象方法是什么? 只有方法签名,没有方法体,使用abstract修饰。 3.继承抽象有哪些注意事项? 如果一个类继承了抽象类,那么这个类必须重写抽象类的所有抽象方法。 否则,这一类也必须定义为抽象类。
抽象案例
系统需求 某加油站推出了两种支付卡,一种是预存1万张金卡,后续加油享受80%的折扣,另一种是预存5万张银卡 ,后续加油享受8.5折优惠。 进入出纳系统后,请分别实现两张卡的逻辑,卡需要包含主人的名称、余额、支付功能。
分析实现 创建卡片父类:定义属性包括主人名称、余额、支付功能(具体实现子类) 创建一张白金卡类:重写支付功能,按照原价的8折计算输出。 创建银卡类:重写支付功能,按原价8.五折计算输出。
package com.itheima.d7_abstract_test; public abstract class Card { private String userName; private double money; //定义支付方式,表示卡可以支付。 ///抽象方法 public abstract void pay(double money); public String getUserName() { return userName; } public void setUserName(String userName) { this.userName = userName; } public double getMoney() { return money; } public void setMoney(double money) { this.money = money; } }
package com.itheima.d7_abstract_test; public class GoldCard extends Card { @Override public void pay(double money2) { System.out.println("您目前的消费:" money2); System.out.println("您目前的余额:" getMoney()); //优惠价 double rs=money2*0.8; System.out.println("您实际支付:"+rs); //更新账户余额 setMoney(getMoney()-rs); } }
package com.itheima.d7_abstract_test; public class Test { public static void main(String[] args) { //学习抽象类的基本使用,做父类,被继承,重写抽象方法 GoldCard c=new GoldCard(); c.setMoney(10000); c.setUserName("贾明超"); c.pay(300); System.out.println("剩余:"+c.getMoney()); } }
抽象类的特征、注意事项
特征和注意事项
-
有得有失: 得到了抽象方法,失去了创建对象的能力。
-
抽象类为什么不能创建对象?
-
类有的成员(成员变量、方法、构造器)抽象类都具备
-
抽象类中不一定有抽象方法,有抽象方法的类一定是抽象类
-
一个类继承了抽象类必须重写完抽象类的全部抽象方法,否则这个类也必
须定义成抽象类。
-
不能用abstract修饰变量、代码块、构造器。
final和abstract是什么关系?
-
互斥关系
-
abstract定义的抽象类作为模板让子类继承,final定义的类不能被继承。
-
抽象方法定义通用功能让子类重写,final定义的方法子类不能重写。
-
抽象类的应用知识:模板方法模式
-
使用场景说明:当系统中出现同一个功能多处在开发,而该功能中大部分代码是一样的,只有其中部分可能不同的时候。
使用步骤
-
把功能定义成一个所谓的模板方法,放在抽象类中,模板方法中只定义通用且能确定的代码。
-
模板方法中不能决定的功能定义成抽象方法让具体子类去实现。
package com.itheima.d9_abstract_template; public abstract class Student { //正式声明了模板方法模式 public final void write(){//防止子类重写以防改模板 System.out.println("\t\t\t\t我的爸爸"); System.out.println("你的爸爸是啥样"); //正文(每个子类都要写的,每个子类写的情况不一样) //因此,模板方法把正文部分定义成抽象方法,交给具体的子类来完成 System.out.println(writeMain());//就近选择子类重写的方法 System.out.println("我的爸爸简直太好了"); } public abstract String writeMain(); }
package com.itheima.d9_abstract_template; public class StudentChild extends Student { @Override public String writeMain() { return"我的爸爸太牛了"; } }
package com.itheima.d9_abstract_template; public class StudentMiddle extends Student{ @Override public String writeMain() { return "我的爸爸也很牛"; } }
package com.itheima.d9_abstract_template; public class Test { public static void main(String[] args) { //模板方法模式思想和使用步骤。 //写作文,中学生和小学生都写《我的爸爸》,开头结尾固定,正文自由发挥。 StudentMiddle s=new StudentMiddle(); s.write(); StudentChild s2=new StudentChild(); s2.write(); } }
模板方法我们是建议使用final修饰的,这样会更专业**
总结
-
模板方法模式解决了什么问题?
-
极大的提高了代码的复用性
-
模板方法已经定义了通用结构,模板不能确定的定义成抽象方法。
-
使用者只需要关心自己需要实现的功能即可。
-
-
-
接口
接口概述、特点
接口的定义与特点
-
接口的格式如下:
接口用关键字interface来定义 public interface 接口名 { // 常量 // 抽象方法 }
-
JDK8之前接口中只能是抽象方法和常量,没有其他成分了。
-
接口不能实例化。
-
接口中的成员都是public修饰的,写不写都是,因为规范的目的是为了公开化。
package com.itheima.d10_interface; //声明的接口:体现了一种规范,规范一定是公开的。 public interface InterfaceDome { //接口中的成分特点:JDK8之前接口中只有抽象方法和常量 //1.常量 // public static final String SCHOOL_NAME="黑马程序员"; String SCHOOL_NAME="黑马程序员"; //2.抽象方法 //注意:由于接口体现规范思想,规范默认都是公开的,所以代码层面,public abstract可以省略不写。 // public abstract void run(); void run(); }
接口的基本使用:被实现
接口的用法:
-
接口是用来被类实现(implements)的,实现接口的类称为实现类。实现类可以理解成所谓的子类。
修饰符 class 实现类 implements 接口1, 接口2, 接口3 , ... { } 实现的关键字:implements
从上面可以看出,接口可以被类单实现,也可以被类多实现。
接口实现的注意事项:
-
一个类实现接口,必须,否则这个类需要定义成抽象类。
package com.itheima.d11_implements; public interface Law { void rule(); }
package com.itheima.d11_implements; public interface SportMan { void run(); void competition(); }
package com.itheima.d11_implements; public class PingpongMan implements SportMan,Law{ private String name; public PingpongMan(String name) { this.name = name; } @Override public void run() { System.out.println(name+"必须训练"); } @Override public void competition() { System.out.println(name+"必须参加比赛"); } @Override public void rule() { } }
package com.itheima.d11_implements; public class Test { public static void main(String[] args) { //理解接口的基本使用,被类实现。 PingpongMan p=new PingpongMan("张继科"); p.run(); p.competition(); p.rule(); } }
接口与接口的关系:多继承
基本小结
-
类和类的关系:单继承。
-
类和接口的关系:多实现。
-
接口和接口的关系:多继承,一个接口可以同时继承多个接口。
接口多继承的作用
规范合并,,便于子类实现。
JDK8开始接口新增方法
正在上传…重新上传取消
正在上传…重新上传取消
正在上传…重新上传取消
总结
-
JDK8开始后新增了那些方法?
-
默认方法:default修饰,实现类对象调用。
-
静态方法:static修饰,必须用当前接口名调用
-
私有方法:private修饰,jdk9开始才有的,只能在接口内部被调用。 他们都会默认被public修饰。
使用接口的注意事项
1、接口不能创建对象 2、一个类实现多个接口,多个接口中有同样的静态方法不冲突。 3、一个类继承了父类,同时又实现了接口,父类中和接口中有同名方法,默认用父类的。 4、一个类实现了多个接口,多个接口中存在同名的默认方法,不冲突,这个类重写该方法即可。 5、一个接口继承多个接口,是没有问题的,如果多个接口中存在规范冲突则不能多继承。
面向对象三大特征之三:多态
多态的概述,多态的形式
什么是多态?
-
同类型的对象,执行同一个行为,会表现出不同的行为特征。
多态的常见形式
父类类型 对象名称 = new 子类构造器; 接口 对象名称 = new 实现类构造器;
多态中成员访问特点
多态的前提
package com.itheima.d1_polymorphic; public abstract class Animal { public String name="父类动物"; public abstract void run(); }
package com.itheima.d1_polymorphic; public class Dog extends Animal{ public String name="子类狗"; @Override public void run() { System.out.println("狗跑的贼快"); } }
package com.itheima.d1_polymorphic; public class Tortoise extends Animal{ public String name="子类乌龟"; @Override public void run() { System.out.println("乌龟根本不会跑"); } }
package com.itheima.d1_polymorphic; public class Test { public static void main(String[] args) { //1.多态的形式: Animal a=new Dog(); a.run();//方法调用:编译看左边,运行看右边 System.out.println(a.name);//变量调用:编译运行都看左 Animal a2=new Tortoise(); a2.run(); System.out.println(a2.name);//父类动物 } }
多态的好处
优势
在多态形式下,右边对象可以实现解耦合,便于扩展和维护。 定义方法的时候,使用父类型作为参数,该方法就可以接收这父类的一切子类对象,体现出多态的扩展性与便利。
Animal a = new Dog(); a.run(); // 后续业务行为随对象而变,后续代码无需修改
多态下会产生的一个问题:
多态下不能使用子类的独有功能
多态下引用数据类型的类型转换
自动类型转换(从子到父):
-
子类对象赋值给父类类型的变量指向。
强制类型转换吗(从父到子)
-
此时必须进行强制类型转换:子类 对象变量 = (子类)父类类型的变量
-
注意: 如果转型后的类型和对象真实类型不是同一种类型,那么在转换的时候就会出现ClassCastException
-
变量名 instanceof 真实类型 判断关键字左边的变量指向的对象的真实类型,是否是右边的类型或者是其子类类型,是则返回true,反之。
package com.itheima.d3_polymorphic_convert.d1_polymorphic; public abstract class Animal { public String name="父类动物"; public abstract void run(); }
package com.itheima.d3_polymorphic_convert.d1_polymorphic; public class Dog extends Animal { public String name="子类狗"; @Override public void run() {System.out.println("狗跑的贼快");} //独有功能 public void lookDoor(){ System.out.println("狗在看门"); } }
package com.itheima.d3_polymorphic_convert.d1_polymorphic; public class Tortoise extends Animal { public String name="子类乌龟"; @Override public void run() { System.out.println("乌龟根本不会跑"); } public void leyEggs(){ System.out.println("乌龟会下蛋"); } }
package com.itheima.d3_polymorphic_convert.d1_polymorphic; public class Test { public static void main(String[] args) { //自动类型转换 Animal a=new Dog(); a.run(); //强制类型转换 Animal a2=new Tortoise(); a2.run(); // Dog d= (Dog) a2;//强制类型转换,编译阶段不报错。(注意:有继承或者实现关系编译阶段可以强转。运行时可能出错) if(a2 instanceof Tortoise){ Tortoise t= (Tortoise) a2; t.leyEggs(); }else if(a2 instanceof Dog){ Dog d=new Dog(); d.lookDoor(); } System.out.println("............................"); go(new Dog()); go(new Tortoise()); } public static void go(Animal a){ a.run(); //不知道a是狗还是乌龟 if(a instanceof Tortoise){ Tortoise t= (Tortoise) a; t.leyEggs(); }else if(a instanceof Dog){ Dog d= (Dog) a; d.lookDoor(); } } }
总结
-
引用数据类型的类型转换,有几种方式? 自动类型转换、强制类型转换。
-
强制类型转换能解决什么问题?强制类型转换需要注意什么。
a. 可以转换成真正的子类类型,从而调用子类独有功能。
b.有继承关系/实现的2个类型就可以进行强制转换,编译无问题。 c.运行时,如果发现强制转换后的类型不是对象真实类型则报错。 类型转换异常:ClassCastException
多态的综合案例
需求: 使用面向对象编程模拟:设计一个电脑对象,可以安装2个USB设备 鼠标:被安装时可以完成接入、调用点击功能、拔出功能。 键盘:被安装时可以完成接入、调用打字功能、拔出功能。 分析 定义一个USB的接口(申明USB设备的规范必须是:可以接入和拔出)。 提供2个USB实现类代表鼠标和键盘,让其实现USB接口,并分别定义独有功能。 创建电脑对象,创建2个USB实现类对象,分别安装到电脑中并触发功能的执行。
package com.itheima.d4_polymorphic_test; public class Computer { private String name; public Computer(String name) { this.name = name; } public void start(){ System.out.println(name+"开机了"); } // 提供安装USB设备的入口 public void installUSB(USB usb){ //多态。父类接口作为入参。usb可能是鼠标还可能是键盘 usb.connect(); //独有功能:判断 强转 if (usb instanceof KeyBoard){ KeyBoard k= (KeyBoard) usb; k.keyDown(); }else if(usb instanceof Mouse){ Mouse m= (Mouse) usb; m.dbClick(); } usb.unconnect(); } public String getName() { return name; } public void setName(String name) { this.name = name; } }
package com.itheima.d4_polymorphic_test; //USB接口==规范 public interface USB { //接入 拔出 void connect(); void unconnect(); }
package com.itheima.d4_polymorphic_test; public class KeyBoard implements USB{ private String name; //独有功能 public void keyDown(){ System.out.println(name+"敲击了"); } public KeyBoard(String name) { this.name = name; } public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public void connect() { System.out.println("成功连接了电脑"); } @Override public void unconnect() { System.out.println("成功断开了电脑"); } }
package com.itheima.d4_polymorphic_test; public class Mouse implements USB{ private String name; //独有功能 public void dbClick(){ System.out.println(name+"双击点亮小红心"); } public Mouse(String name) { this.name = name; } public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public void connect() { System.out.println("成功连接了电脑"); } @Override public void unconnect() { System.out.println("成功断开了电脑"); } }
package com.itheima.d4_polymorphic_test; //定义一个USB的接口(申明USB设备的规范必须是:可以接入和拔出)。 // 提供2个USB实现类代表鼠标和键盘,让其实现USB接口,并分别定义独有功能。 // 创建电脑对象,创建2个USB实现类对象,分别安装到电脑中并触发功能的执行。 public class Test { public static void main(String[] args) { //1.创建电脑对象 Computer c=new Computer("外星人"); c.start(); //2.创建鼠标对象,键盘对象 USB u=new KeyBoard("双飞燕"); c.installUSB(u); USB u1=new Mouse("罗技鼠标"); c.installUSB(u1); } }
内部类
内部类概述
内部类
-
内部类就是定义在一个类里面的类,里面的类可以理解成(寄生),外部类可以理解成(宿主)。
-
public class People{ // 内部类 public class Heart{ } }
内部类的使用场景、作用
-
当一个事物的内部,还有一个部分需要一个完整的结构进行描述,而这个内部的完整的结构又只为外部事物提供服务,那么整个内部的完整结构可以选择使用内部类来设计。
-
内部类通常可以方便访问外部类的成员,包括私有的成员。
-
内部类提供了内部类本身就可以用private protectecd等修饰,封装性可以做更多控制。
内部类的分类
-
静态内部类[了解]
-
成员内部类(非静态内部类) [了解]
-
局部内部类[了解]
-
匿名内部类(重点)
内部类之一:静态内部类[了解]
什么是静态内部类?
-
有static修饰,属于外部类本身。
-
它的特点和使用与普通类是完全一样的,类有的成分它都有,只是位置在别人里面而已。
public class Outer{ // 静态成员内部类 public static class Inner{ } }
-
静态内部类创建对象的格式:
外部类名.内部类名 对象名 = new 外部类名.内部类构造器; 范例:Outer.Inner in = new Outer.Inner();
package com.itheima.d5_innerclass_static; //外部类 public class Outer { public static int a=100; private String hobby; public static class Inner{ private String name; private int age; public static String schoolName; public Inner() { } public Inner(String name, int age) { this.name = name; this.age = age; } public void show(){ System.out.println("名称:"+name); System.out.println(a); // System.out.println(hobby); // Outer o=new Outer(); // System.out.println(o.hobby);可以直接访问外部类的静态成员,不能直接访问外部类的实例成员。 } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public static String getSchoolName() { return schoolName; } public static void setSchoolName(String schoolName) { Inner.schoolName = schoolName; } } }
package com.itheima.d5_innerclass_static; public class Test { public static void main(String[] args) { Outer.Inner in=new Outer.Inner(); in.setName("张三");//张三 in.show();//100 } }
静态内部类的访问拓展:
内部类之二:成员内部类[了解]
什么是成员内部类?
-
无static修饰,
public class Outer { // 成员内部类 public class Inner { } }
-
JDK16之前,成员内部类中不能定义静态成员,JDK 16开始也可以定义静态成员了。
-
成员内部类创建对象的格式:
格式: 外部类名.内部类名 对象名 = new 外部类构造器.new 内部类构造器(); 范例: Outer.Inner in = new Outer().new Inner();
成员内部类的访问扩展
package com.itheima.d6_innerclass; //外部类 public class Outer { //成员内部类:不能加static修饰 public static int num=11; private String hobby; public Outer() { } public Outer(String hobby) { this.hobby = hobby; } public class Inner { private String name; private int age; public static int a=100;//JDK 16开始也可以定义静态成员了 public static void test(){ System.out.println(a); } public void show() { System.out.println("名称:"+name); System.out.println("数量:"+num); System.out.println("爱好:"+hobby); } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public static int getA() { return a; } public static void setA(int a) { Inner.a = a; } } }
package com.itheima.d6_innerclass; public class Test { public static void main(String[] args) { Outer.Inner in=new Outer().new Inner(); in.setName("内部"); in.show(); Outer.Inner.test(); System.out.println("......................"); Outer.Inner in1=new Outer("爱学习").new Inner(); in1.show(); } } //名称:内部 数量:11 爱好:null 100 ...................... 名称:null 数量:11 爱好:爱学习
内部类之三:局部内部类[了解]
局部内部类 (鸡肋语法,了解即可) 局部内部类放在方法、代码块、构造器等执行体中。 局部内部类的类文件名为: 外部类$N内部类.class。
内部类之四:匿名内部类概述[重点]
匿名内部类:
本质上是一个没有名字的,定义在方法中、代码块中、等。 :方便创建子类对象,最终目的为了简化代码编写。
格式:
new 类|抽象类名|或者接口名() { 重写方法; };
Animal a = new Animal() { public void run() { } }; a. run();
(可以理解为既是一个类也是一个对象)
特点总结:
-
匿名内部类是一个没有名字的内部类。
-
匿名内部类的对象类型。
匿名内部类常见使用形式
Test1
package com.itheima.d8_innerclass_anoymous; public class Test { public static void main(String[] args) { Animal a=new Animal() { @Override public void run() { System.out.println("老虎跑得快"); } }; a.run(); } } //class Tiger extends Animal{ // @Override // public void run() { // System.out.println("老虎跑得快"); // } //} abstract class Animal{ public abstract void run(); } 老虎跑得快
Test2
package com.itheima.d8_innerclass_anoymous; //掌握匿名内部类的使用形式(语法) public class Test2{ public static void main(String[] args) { // Swimming s=new Student(); Swimming s=new Swimming() { @Override public void swim() { System.out.println("学生自由泳"); } }; go(s); System.out.println(".................."); Swimming s1=new Swimming() { @Override public void swim() { System.out.println("老师游得贼快"); } }; go(s1); System.out.println("................."); go(new Swimming() { @Override public void swim() { System.out.println("运动员游得贼快"); } }); } //学生老师运动员可以一起参加比赛 //接口充当一种父类,所有子类都可以送进来 public static void go(Swimming s){ System.out.println("开始"); s.swim(); System.out.println("结束"); } } //class Student implements Swimming{ // @Override // public void swim() { // System.out.println("学生快乐的游泳"); // } //} //会游泳 interface Swimming{ void swim(); } 开始 学生自由泳 结束 .................. 开始 老师游得贼快 结束 ................. 开始 运动员游得贼快 结束
匿名内部类真实使用场景演示
正在上传…重新上传取消
常用API
Object
Object类的方法
-
Object类的方法是,所以我们要学习Object类的方法。
-
一个类要么默认继承了Object类,要么间接继承了Object类,Object类是Java中的祖宗类。
PUBLIC STRING TOSTRING() 默认是返回当前对象在堆内存中的地址信息: public boolean equals(Object o) 默认是比较当前对象与另一个对象的地址是否相同,相同返回true,不同返回false
toString方法
问题引出
开发中直接输出对象,默认输出对象的地址其实是毫无意义的。 开发中输出对象变量,更多的时候是希望看到对象的内容数据而不是对象的地址信息。
toString存在的意义
父类toString()方法存在的意义就是为了,以便返回对象的!!
equals方法
问题提出
直接比较两个对象的地址是否相同完全可以用“==”替代equals。
equals存在的意义
父类equals方法存在的意义就是为了
总结
Object的equals方法的作用是什么?
-
默认是与另一个对象比较地址是否一样
-
让子类重写,以便比较2个子类对象的内容是否相同。
package com.itheima.d9_api_object; import java.util.Objects; public class Student {//extends Object private String name; private char sex; private int age; public Student() { } public Student(String name, char sex, int age) { this.name = name; this.sex = sex; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public char getSex() { return sex; } public void setSex(char sex) { this.sex = sex; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } //重写equals,自己定制相等规则。两个对象内容一样就认为是相等的。比较者:s1==this(谁调这个方法,this就代表谁) // 被比较者:s2==>o // @Override // public boolean equals(Object o) { // //1.判断o是不是学生类型 // if (o instanceof Student) { // Student s2 = (Student) o;//强转成学生类型,才能调用学生类中的独有属性 // //2.判断两个对象内容是否一样 if (this.name.equals(s2.name) && this.age == s2.age && this.sex == s2.sex) { return true; }else{ return false; } // return this.name.equals(s2.name) && this.age == s2.age && this.sex == s2.sex; // } else { // //学生只能和学生比,否则结果一定是false // return false; // } // } @Override public boolean equals(Object o) { //1.判断是否为同一个对象比较,如果是返回true if (this == o) return true; //2.如果o==null 返回false,如果o不是学生类型返回false if (o == null || getClass() != o.getClass()) return false; Student student = (Student) o; return sex == student.sex && age == student.age && Objects.equals(name, student.name); } @Override public int hashCode() { return Objects.hash(name, sex, age); } @Override public String toString() { return "Student{" + "name='" + name + '\'' + ", sex=" + sex + ", age=" + age + '}'; } }
package com.itheima.d9_api_object; public class Test1 { public static void main(String[] args) { //掌握object类中toString方法的使用 Student s=new Student("贾明超",'男',19); String rs=s.toString(); System.out.println(rs); //直接输出对象变量,默认可以省略toString调用不写的 System.out.println(s); } }
package com.itheima.d9_api_object; //掌握Object类中equals方法的使用 public class Test2 { public static void main(String[] args) { Student s1=new Student("贾明超",'男',19); Student s2=new Student("贾明超",'男',19); //equals默认是比较两个不同的对象对象地址是否相同 System.out.println(s1.equals(s2));//true 重写后 System.out.println(s1 == s2);//false } }
Objects
Objects是一个工具类,提供了一些方法去完成一些功能。
官方在进行字符串比较时,没有用字符串对象的的equals方法,而是选择了Objects的equals方法来比较。
@Override public boolean equals(Object o) { // 1、判断是否是同一个对象比较,如果是返回true。 if (this == o) return true; // 2、如果o是null返回false 如果o不是学生类型返回false ...Student != ..Pig if (o == null || this.getClass() != o.getClass()) return false; // 3、说明o一定是学生类型而且不为null Student student = (Student) o; return sex == student.sex && age == student.age && Objects.equals(name, student.name); }
方法名 | 说明 |
---|---|
public static boolean equals(Object a, Object b) | 比较两个对象的,底层会,从而可以避免空指针异常。 |
public static boolean isNull(Object obj) | 判断变量是否为null ,为null返回true ,反之 |
package com.itheima.d10_api_objects; import java.util.Objects; //掌握objects类的常用方法:equals public class Test { public static void main(String[] args) { String s1=null; String s2=new String("itheima"); // System.out.println(s1.equals(s2));//留下了隐患,可能出现了空指针异常。 System.out.println(Objects.equals(s1,s2));//false 更安全,结果也是对的 System.out.println(Objects.isNull(s1));//true System.out.println(s1==null);//true System.out.println(Objects.isNull(s2));//false System.out.println(s2==null);//false } }
StringBuilder
方法名称 | 说明 |
---|---|
public StringBuilder append(任意类型) | 添加(连接)数据并返回StringBuilder对象本身 |
public StringBuilder reverse() | 将对象的内容反转 |
public int length() | 返回对象内容长度 |
public String toString() | 通过toString()就可以实现把StringBuilder转换为String |
-
String :内容是不可变的、拼接字符串性能差。
-
StringBuilder:内容是可变的、拼接字符串性能好、代码优雅。
-
定义字符串使用String
-
拼接、修改等操作字符串使用StringBuilder
package com.itheima.d11_api_StringBuilder; public class StringBuilderDome1 { public static void main(String[] args) { StringBuilder sb=new StringBuilder(); sb.append("a"); sb.append("abc"); sb.append(1); System.out.println(sb); StringBuilder sb1=new StringBuilder(); //支持链式编程 sb1.append("a").append("b").append("我爱你中国"); System.out.println(sb1);//ab我爱你中国 //反转 sb1.reverse().append("110"); System.out.println(sb1);//国中你爱我ba110 //长度 System.out.println(sb1.length()); //注意:目的StringBuilder只是拼接字符串的手段,效率好。 //最终的还是要恢复String类型。 StringBuilder sb2=new StringBuilder(); sb2.append("123").append("456"); //恢复 String String rs=sb2.toString(); check(rs); } public static void check (String data){ System.out.println(data); } }
package com.itheima.d11_api_StringBuilder; public class StringBuilderTest2 { public static void main(String[] args) { int []arr1=null; System.out.println(toString(arr1)); int []arr2={10,20,30}; System.out.println(toString(arr2)); } //1.定义方法接受任意整型数组,返回数组内容格式 public static String toString(int[] arr) { if (arr != null) { //2.开始拼接内容 StringBuilder sb = new StringBuilder("[");//可以用有参构造器 for (int i = 0; i < arr.length; i++) { sb.append(arr[i]).append(i == arr.length - 1 ? "" : ", "); } sb.append("]"); return sb.toString(); } else { return null; } } }
Math
Math类
包含执行基本数字运算的方法,Math类没有提供公开的构造器,相当于一个工具类,不能创建对象。 如何使用类中的成员呢?看类的成员是否都是静态的,如果是,通过类名就可以直接调用.
Math类常用方法
方法名 | 说明 |
---|---|
public static int (int a) | |
public static double ceil(double a) | 向上取整 |
public static double floor(double a) | 向下取整 |
public static int round(float a) | 四舍五入 |
public static int max(int a,int b) | 获取两个int值中的较大值 |
public static double ( ) | * ** |
public static double random() | 返回值为double的值,*[0.0,1.0)** |
package com.itheima.d12_math; /** 目标:Math类的使用。 Math用于做数学运算。 Math类中的方法全部是静态方法,直接用类名调用即可。 方法: 方法名 说明 public static int abs(int a) 获取参数a的绝对值: public static double ceil(double a) 向上取整 public static double floor(double a) 向下取整 public static double pow(double a, double b) 获取a的b次幂 public static long round(double a) 四舍五入取整 小结: 记住。 */ public class MathDome { public static void main(String[] args) { // 1.取绝对值:返回正数 System.out.println(Math.abs(10)); // 10 System.out.println(Math.abs(-10.3)); // 10.3 // 2.向上取整: 5 System.out.println(Math.ceil(4.00000001)); // 5.0 System.out.println(Math.ceil(4.0)); // 4.0 // 3.向下取整:4 System.out.println(Math.floor(4.99999999)); // 4.0 System.out.println(Math.floor(4.0)); // 4.0 // 4.求指数次方 System.out.println(Math.pow(2 , 3)); // 2^3 = 8.0 // 5.四舍五入 10 System.out.println(Math.round(4.49999)); // 4 System.out.println(Math.round(4.500001)); // 5 System.out.println(Math.random()); // 0.0 - 1.0 (包前不包后) // 拓展: 3 - 9 之间的随机数 (0 - 6) + 3 // [0 - 6] + 3 int data = (int)(Math.random() * 7) + 3; System.out.println(data); } }
System
System 类概述
System也是一个工具类,代表了当前系统,提供了一些与系统相关的方法。
System类常用方法
方法名 | 说明 |
---|---|
public static void exit(int status) | 终止当前运行的 Java 虚拟机, |
public static long () | 返回当前系统的时间毫秒值形式 |
public static void arraycopy(数据源数组, 起始索引, 目的地数组, 起始索引, 拷贝个数) | 数组拷贝 |
package com.itheima.d13_system; import java.lang.reflect.Array; import java.util.Arrays; public class SystemDemo { public static void main(String[] args) { System.out.println("程序开始"); // System.exit(0);//JVM终止!静态方法属于类,用类调用。 0表示正常终止。 System.out.println("程序结束"); // 2.计算机认为时间是有起点的,起始时间: 1970年1月1日 00:00:00 // 时间毫秒值:指的是从1970年1月1日 00:00:00走到此刻的总的毫秒数,应该是很大的。 1s = 1000ms。 long time=System.currentTimeMillis(); System.out.println(time); long startTime=System.currentTimeMillis(); //进行时间的计算:性能分析 for (int i = 0; i < 100000; i++) { System.out.println("输出:"+i); } long endTime=System.currentTimeMillis(); System.out.println((endTime-startTime)/1000.0+"s"); //3.数组拷贝 // 参数一:被拷贝的数组 // 参数二:从那个索引位置开始拷贝 // 参数三:复制的目标数组 // 参数四:粘贴位置 // 参数五:拷贝元素的个数 int[] arr1={10,20,30,40}; int[] arr2=new int[4];//[0,0,0,0]==>[0,0,30,40] System.arraycopy(arr1,2,arr2,2,2); System.out.println(Arrays.toString(arr2)); } }
BigDecimal
BigDecimal作用
用于解决浮点型运算精度失真的问题
使用步骤
创建对象BigDecimal封装浮点型数据(最好的方式是调用方法)
public static BigDecimal valueOf(double val):包装浮点数成为BigDecimal对象。
package com.itheima.d14_bigdecimal; import java.math.BigDecimal; import java.math.RoundingMode; import java.text.NumberFormat; /** 目标:BigDecimal大数据类。 引入: 浮点型运算的时候直接+ * / 可能会出现数据失真(精度问题)。 BigDecimal可以解决浮点型运算数据失真的问题。 BigDicimal类: 包:java.math. 创建对象的方式(最好的方式:) public static BigDecimal valueOf(double val) :包装浮点数成为大数据对象。 方法声明 public BigDecimal add(BigDecimal value) 加法运算 public BigDecimal subtract(BigDecimal value) 减法运算 public BigDecimal multiply(BigDecimal value) 乘法运算 public BigDecimal divide(BigDecimal value) 除法运算 public double doubleValue(): 把BigDecimal转换成double类型。 */ public class BigDecimalDemo { public static void main(String[] args) { // 浮点型运算的时候直接+ * / 可能会出现数据失真(精度问题)。 System.out.println(0.09 + 0.01); System.out.println(1.0 - 0.32); System.out.println(1.015 * 100); System.out.println(1.301 / 100); System.out.println("-------------------------"); double a = 0.1; double b = 0.2; double c = a + b; System.out.println(c); System.out.println("--------------------------"); // 包装浮点型数据成为大数据对象 BigDeciaml BigDecimal a1 = BigDecimal.valueOf(a); BigDecimal b1 = BigDecimal.valueOf(b); BigDecimal c1 = a1.add(b1); // BigDecimal c1 = a1.subtract(b1); // BigDecimal c1 = a1.multiply(b1); // BigDecimal c1 = a1.divide(b1); System.out.println(c1); // 目的:double double rs = c1.doubleValue(); System.out.println(rs); // 注意事项:BigDecimal是一定要精度运算的 BigDecimal a11 = BigDecimal.valueOf(10.0); BigDecimal b11 = BigDecimal.valueOf(3.0); /** 参数一:除数 参数二:保留小数位数 参数三:舍入模式 */ BigDecimal c11 = a11.divide(b11, 2, RoundingMode.HALF_UP); // 3.3333333333 System.out.println(c11); System.out.println("-------------------"); } } 0.09999999999999999 0.6799999999999999 101.49999999999999 0.013009999999999999 ------------------------- 0.30000000000000004 -------------------------- 0.3 0.3 3.33 -------------------
BigDecima常用API
方法名 | 说明 |
---|---|
public BigDecimal add(BigDecimal b) | 加法 |
public BigDecimal subtract(BigDecimal b) | 减法 |
public BigDecimal multiply(BigDecimal b) | 乘法 |
public BigDecimal divide(BigDecimal b) | 除法 |
public BigDecimal divide (另一个BigDecimal对象,精确几位,舍入模式) | 除法 |
日期与时间
Date 类
Date类概述
Date类代表当前所在系统的日期时间信息。
Date的构造器
名称 | 说明 |
---|---|
public Date() | 创建一个Date对象,代表的是系统当前日期时间。 |
Date的方法
名称 | 说明 |
---|---|
public long getTime() | 返回从1970年1月1日 00:00:00走到此刻的总的毫秒数 |
案例
请计算出当前时间往后走1小时121秒之后的时间是多少。
时间毫秒值 -> 日期对象
构造器 | 说明 |
---|---|
public Date(long time) | 把时间毫秒值转换成Date日期对象。 |
DATE方法 | 说明 |
---|---|
public void setTime(long time) | 设置日期对象的时间为当前时间毫秒值对应的时间 |
package com.itheima.d1_date; import java.util.Date; //目标:学会使用 data类处理时间,获取时间信息。 public class DataDemo1 { public static void main(String[] args) { //1.创建一个Data类对象,代表系统此刻的日期时间对象 Date d=new Date(); System.out.println(d); //2.获取时间毫秒值 long time=d.getTime(); System.out.println(time); long time1=System.currentTimeMillis(); System.out.println(time1); System.out.println("...................."); //1.得到当前时间的毫秒值 Date d1=new Date(); System.out.println(d1); //2.当前时间往后走1小时121秒 long time2=System.currentTimeMillis(); time2+=(60*60+121)*1000; //3.把时间毫秒值转换成对应的日期对象 // Date d2=new Date(time2); // System.out.println(d2); Date d3=new Date(); d3.setTime(time2); System.out.println(d3); } } Mon Apr 11 14:25:23 CST 2022 1649658323951 1649658323981 .................... Mon Apr 11 14:25:23 CST 2022 Mon Apr 11 15:27:24 CST 2022
总结
-
日期对象如何创建,如何获取时间毫秒值?
-
public Date();
-
public long getTime();
-
-
时间毫秒值怎么恢复成日期对象
-
public Date(long time);
-
public void setTime(long time);
SimpleDateFormat
正在上传…重新上传取消
正在上传…重新上传取消
正在上传…重新上传取消
SimpleDateFormat 类作用
可以去完成日期时间的格式化操作
正在上传…重新上传取消
构造器
构造器 | 说明 |
---|---|
public SimpleDateFormat(String pattern) | 构造一个SimpleDateFormat,使用指定的格式 |
格式化方法
格式化方法 | 说明 |
---|---|
public final String | 将日期格式化成日期/时间字符串 |
public final String | 将时间毫秒值式化成日期/时间字符串 |
正在上传…重新上传取消
SimpleDateFormat解析字符串时间成为日期对象
解析字符串时间成为日期对象: 2011-11-11 11:11:22 -> Date日期对象
package com.itheima.d2_simpledateformat; import java.text.SimpleDateFormat; import java.util.Date; public class SimpleDateFormatDemo1 { // SimpleDateFormatDemo1简单日期格式化类的使用 //格式化时间 解析时间 public static void main(String[] args) { //1.日期对象 Date d=new Date(); System.out.println(d); //2.格式化这个日期对象(指定格式化形式) SimpleDateFormat sdf=new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss EEE a"); //3.开始格式化日期对象成为喜欢的字符串形式 String rs= sdf.format(d); System.out.println(rs); //4.格式化时间毫秒值.121秒后的时间 long time1=System.currentTimeMillis()+121*1000; String rs2= sdf.format(time1); System.out.println(rs2); System.out.println(sdf.format(time1)); } } Mon Apr 11 14:46:36 CST 2022 2022年04月11日 14:46:36 周一 下午 2022年04月11日 14:48:37 周一 下午 2022年04月11日 14:48:37 周一 下午
案例
请计算出 2021年08月06日11点11分11秒,往后走2天14小时49分06秒后的时间是多少。
解析方法 | 说明 |
---|---|
public Date **parse(String source)** | 从给定字符串的开始解析文本以生成日期 |
package com.itheima.d2_simpledateformat; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; public class SimpleDateFormatDemo2 { public static void main(String[] args) throws ParseException { //目标:学会使用SimpleDateFormat解析字符串成为日期对象 //请计算出 2021年08月06日11点11分11秒,往后走2天14小时49分06秒后的时间是多少。 //1.把字符串拿到程序中来 String datestr="2021年08月06日11:11:11"; //2.把字符串时间解析成日期对象(重点):形式必须与被解析时间的形式完全一样,否则运行时解析报错。 SimpleDateFormat sdf=new SimpleDateFormat("yyyy年MM月dd日HH:mm:ss"); Date d=sdf.parse(datestr); //3.往后走 long time=d.getTime()+(2L*24*60*60+14*60*60+49*60+6)*1000; //4.格式化这个时间毫秒值 System.out.println(sdf.format(time)); } }
总结
1.SimleDateFormat可以格式化哪些时间形式,? Date日期对象,时间毫秒值。 2、SimpleDateFormat如何进行字符串时间的解析的? 通过一个方法: public Date parse(String source)
Test秒杀活动
需求 某购物网站举办秒杀活动,开始时间和结束时间如左图所示,当前活动结束后,系统记录到2位用户的付款时间分别如下: 小贾下单并付款的时间为:2020年11月11日 0:03:47 小皮下单并付款的时间为:2020年11月11日 0:10:11 规则:顾客的付款时间必须在秒杀时间之内,请判断出两位顾客是否秒杀成功。 分析 把4个字符串形式的时间解析成日期对象。 判断小贾和小皮的时间是否在秒杀时间范围之内,并给出相应的提示。
package com.itheima.d2_simpledateformat; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; public class SimpleDateFormatTest3 { public static void main(String[] args) throws ParseException { //1.开始时间和结束时间 String startTime="2021-11-11 00:00:00"; String endTime="2021-11-11 00:10:00"; //2.小贾 小皮 String xiaoJia="2021-11-11 0:03:47"; String xiaoPi="2021-11-11 0:10:11"; //3.解析他们的时间(否则计算机无法识别) SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); Date d1=sdf.parse(startTime); Date d2=sdf.parse(endTime); Date d3=sdf.parse(xiaoJia); Date d4=sdf.parse(xiaoPi); if(d3.after(d1)&&d3.before(d2)){ System.out.println("小贾秒杀成功"); }else { System.out.println("小贾秒杀失败"); } if(d4.after(d1)&&d4.before(d2)){ System.out.println("小皮秒杀成功"); }else{ System.out.println("小皮秒杀失败"); } } }
Calendar
Calendar概述
-
Calendar代表