一、封装
概念:把属性设为private,隐藏内部细节限制外部直接访问,提供公共的get和set方法间接访问,提升安全性。
get方法用于获取内部属性
set方法用于设置内部属性的值
二、面向对象三大特点(三大特征)
封装、继承、多态
三、继承
子类继承父类,所有非私有的属性和方法(不包含构造器和主方法)
Java只能单一继承,一个类只能有一个父类(可以通过多重继承来实现多继承)
(所有的类都直接或间接继承了Object,Object万类之祖)
动物继承案例1
Animal
/**
* 动物类
* 名字、吃的方法
*/
public abstract class Animal {
private String name;
/**
* 不明确是什么动物?吃的东西也不明确
*/
public abstract void eat();
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
Cat
/**
* 猫类
* 继承动物类的属性和行为
*/
public class Cat extends Animal{
/**
* 猫吃鱼
*/
@Override
public void eat() {
System.out.println(super.getName()+"吃鱼");
}
}
Dog
/**
* 狗类
* 共有属性和行为直接从动物类继承
*/
public class Dog extends Animal{
/**
* 重写了父类的方法
* 由于父类方法不满足使用,根据子类的特性进行重写
*/
@Override
public void eat() {
System.out.println(super.getName()+"啃骨头");
}
}
测试类
/**
* 继承
* Aniaml
* 子类:Dog Cat
*/
public class Test {
public static void main(String[] args) {
//创建Dog类对象
Dog dog = new Dog();
dog.setName("旺财");
dog.eat();
//创建猫类对象
Cat cat = new Cat();
cat.setName("花花");
cat.eat();
}
}
接口:为了弥补类只能单一继承的缺陷,后来演变为一种接口规范
拍摄接口 打电话接口
数码相机 拍照手机 固定电话
给动物都添加一个功能:跳高 Jump()
定义一个Jump接口,所有需要的这个功能的,都实现这个接口
/**
* 接口
* 接口内只能有静态常量
* public static final 默认修饰符
* 接口内的方法都是抽象方法
* public abstract 默认修饰符
*/
public interface Jump {
void jump();
}
/**
* 猫类
* 继承动物类的属性和行为
*/
public class Cat extends Animal implements Jump{
/**
* 猫吃鱼
*/
@Override
public void eat() {
System.out.println(super.getName()+"吃鱼");
}
@Override
public void jump() {
System.out.println(super.getName()+"像猫跳一样在跳高!!!");
}
}
/**
* 狗类
* 共有属性和行为直接从动物类继承
*/
public class Dog extends Animal implements Jump{
/**
* 重写了父类的方法
* 由于父类方法不满足使用,根据子类的特性进行重写
*/
@Override
public void eat() {
System.out.println(super.getName()+"啃骨头");
}
@Override
public void jump() {
System.out.println(super.getName()+"像狗跳一样在跳高!!!");
}
}
/**
* 继承
* Aniaml
* 子类:Dog Cat
*/
public class Test {
public static void main(String[] args) {
//创建Dog类对象
Dog dog = new Dog();
dog.setName("旺财");
dog.eat();
dog.jump();
//创建猫类对象
Cat cat = new Cat();
cat.setName("花花");
cat.eat();
cat.jump();
}
}
多态的案例
概念:
多态=多种形态=多种类型
水:固态类型、液态类型、气态类型
人的身份:学生类型、警察类型、医生类型、狗
汽车人:汽车、机器人
Dog继承了Animal,这个dog对象,我们可以说你是Dog,也可以说你是Animal
然后dog就拥有多种类型=多种形态=多态
狗:狗类型、动物类型、生物类型
先继承,才有多态
什么是多态的使用?
把不同的子类对象都当作共同的父类来看,屏蔽了子类之间直接的差异
可以设计通用的编程,大大提高代码的重用性
饲养员案例描述多态的使用:
饲养员喂狗和猫,有什么共性:
内部类:类中定义类,web中用的不多,主要是JavaGUI中使用较多,感兴趣自行了解
四、异常
异常是程序编译或运行时发生的意外情况
Exception 编译期异常,编译期必须处理
RuntimeException 运行时异常,不必须处理,可以通过调整代码来避免
Error 错误,内存溢出等都是错误,不能解决
异常的解决:
throws抛出异常,不解决,一旦发生程序会崩溃
try-catch捕获异常,解决异常,程序继续运行
/**
* 测试编译期异常
*/
public class Demo01 {
public static void main(String[] args) {
//日期格式化类对象
SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日");
Date date = new Date();
String s = sdf.format(date);//按照指定格式来格式化日期对象
System.out.println("s = " + s);
//解析字符串时,会抛出编译期异常:PaserException
try {//try块放的是可能会发生异常的代码
System.out.println(1);
Date date2 = sdf.parse("2022年07月12日");//抛出了异常?编译期异常
System.out.println(2);
System.out.println("date2 = " + date2);
} catch (ParseException e) {//一旦发生异常被catch语句捕获
System.out.println(3);
//e.printStackTrace();
} finally {//无论try语句是否发生异常,都会执行
System.out.println(4);
}
System.out.println(5);
System.out.println("-->程序执行结束..");
}
}
运行时异常
String s1 = "";
System.out.println(s1.charAt(0));//运行时异常:StringIndexOutofBoundsException
自定义异常(1.继承Exception的编译期异常 2.继承RuntimeException的运行时异常)
/**
* 测试ATM取款
*/
public class Test {
public static void main(String[] args) {
//创建取款机
ATM atm = new ATM();
//创建银行卡
BankCard bankCard = new BankCard();
bankCard.setBalance(5000);//设置卡内余额
//模拟ATM取款
atm.setBankCard(bankCard);//插卡
try {
atm.withdrawMoney();//取款功能
} catch (BalanceNotEnoughException e) {
e.printStackTrace();
}
System.out.println("-->程序运行结束");
}
}
/**
* 银行卡
* 余额
*/
class BankCard{
private double balance; //余额
public double getBalance() {
return balance;
}
public void setBalance(double balance) {
this.balance = balance;
}
}
/**
* ATM机
* 插卡
* 取款
*/
class ATM{
private BankCard bankCard; //ATM机卡槽
/**
* 取款的方法
*/
public void withdrawMoney() throws BalanceNotEnoughException {
System.out.println("--请输入取款金额:");
int money = new Scanner(System.in).nextInt();
//判断卡余额是否足够
if(money<=this.bankCard.getBalance()){
System.out.println("-->提示:取款成功!!");
this.bankCard.setBalance(this.bankCard.getBalance()-money);
System.out.println("-->提示:取款"+money+"元,卡内余额:"+this.bankCard.getBalance());
}else{
//抛出一个余额不足异常
//System.out.println("-->警告:余额不足");
throw new BalanceNotEnoughException();
}
}
public BankCard getBankCard() {
return bankCard;
}
//当作插卡
public void setBankCard(BankCard bankCard) {
this.bankCard = bankCard;
}
}
--请输入取款金额:
5001
cn.hp.demo04.BalanceNotEnoughException: 警告!!账号余额不足!!
at cn.hp.demo04.ATM.withdrawMoney(Test.java:64)
at cn.hp.demo04.Test.main(Test.java:22)
-->程序运行结束
五、常用类库
java.lang包包含了常用类,系统做了设置无需导包即可使用
1、Object
万类之祖:所有的类都间接或直接的继承了Object类
equals()方法
String类继承并重写了Object的equals
== 可以比较基本数据类型的值是否相同,比较引用数据类型的对象是否是同一个
public class Demo01 {
public static void main(String[] args) {
String s1 = new String("abc");
String s2 = new String("abc");
System.out.println(s1.equals(s2));//true
System.out.println(s1==s2);//false
Cat c1 = new Cat("小白");
Cat c2 = new Cat("小黑");
System.out.println(c1==c2);//false
System.out.println(c1.equals(c2));//true 重写过的equals方法
Cat c3 = c1;
System.out.println(c1==c3);//true
}
}
/**
* 猫类
*/
class Cat{
private String name; //名字
/**
* 改写猫类对象的比较规则,重写Object类equals方法
* 只要猫的名字一样就为真
* @param o
* @return
*/
public boolean equals(Object o) {
Cat c = (Cat) o;//向下转型
//比较猫的名字
return this.name.equals(c.name);
}
/*
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Cat cat = (Cat) o;
return Objects.equals(name, cat.name);
}
*/
@Override
public int hashCode() {
return Objects.hash(name);
}
public Cat() {
}
public Cat(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
hashCode()方法
获取对象在堆内存的地址位置叫哈希码
toString()方法
toString方法默认拼接的对象首地址的@符号后的16进制数字就是hashCoe()哈希码
public String toString() {
return getClass().getName() + "@" + Integer.toHexString(hashCode());
}
重写toString就可以改写打印输出对象的内容
toString()不写,默认就调用
//Dog类
class Dog{
private String name;
public Dog() {
}
public Dog(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return name;
}
}
2、String
是字符串常量,一旦创建不可改变
//源码
public final class String
implements java.io.Serializable, Comparable<String>, CharSequence {
/** The value is used for character storage. */
private final char value[];
被final修饰,String类不能被继承
字符串值本质存在private final char value[];
用法和使用:参考JDK1.8API中文文档
3、可变字符串
String:字符串常量,一旦创建不可改变,线程不安全
StringBuffer:可变字符串,创建仍然可以改变,线程安全(数据在多个线程中同步)
StringBuilder:可变字符串,创建仍然可以改变,线程不安全(数据在多个线程中不同步)
用法和使用:参考JDK1.8API中文文档
4、包装类
包装类是为了将八种基本数据类型转为引用类型的形态
基本 包装类
byte Byte
short Short
int Integer
long Long
float Float
double Double
char Character
boolean Boolean
基本数据可以和包装类自动转换:
装箱(基本数据->包装类对象)和拆箱(包装类对象->基本数据)