java基础知识点,封装,继承,多态,instanceof 重点笔记
封装
面向对象的三大核心思想: 封装、继承、多态
1:概念
使一种屏障, 防止对象属性被外界任意访问,提高对象属性的安全性
步骤
-
属性私有化
private 数据类型 属性名;
访问修饰符 含义 作用范围 public 公共的,公开的 任意位置都可访问 private 私有的 只有本类内部可以访问 -
可以根据需求选择性的对属性进行私有化,但是通常情况下所有属性都应该私有化
-
-
提供取值赋值所需的getter\setter方法
-
getter: 取值. 有返回值,无参数
public 返回值类型 getXxx(){ ? ?return 属性名; } Xxx:对应属性名,首字母大写 ? ?如果属性是布尔类型,则该方法名为`isXxx`
-
返回值类型与对应属性保持一致
-
-
setter: 赋值. 没有返回值,有参数
public void setXxx(数据类型 属性名){ ? ?this.属性名=属性名; } Xxx:对应属性名,首字母大写
-
可以根据需求为私有属性添加getter或setter方法,但是通常情况下所有私有属性都应该有配套的getter和setter方法
-
一个getter或setter方法只能操作一个属性
-
使用
给属性加上封装之后,必须通过调用getter和setter方法才能访问属性
取值: 对象名.getXxx()|对象名.isXxx() 赋值: 对象名.setXxx(实参)
package com.by.entity;
?
/**
* 银行卡: 卡号、密码、余额
*/
public class BankCard {
? ?private String cardID;
? ?private String password;
? ?private double balance;
?
? ?//取值
? ?public String getCardID(){
? ? ? ?return cardID;
? }
? ?//赋值
? ?public void setCardID(String cardID){
? ? ?// this.cardID = cardID;
? ? ? ?System.out.println("卡号不可更改");
? }
? ?public String getPassword(){
? ? ? ?return password;
? }
?
? ?public void setPassword(String password) {
? ? ? ?this.password = password;
? }
?
? ?public double getBalance() {
? ? ? ?return balance;
? }
?
? ?public void setBalance(double balance) {
? ? ? ?this.balance = balance;
? }
? ?
?
? ?public BankCard(){}
?
? ?public BankCard(String cardID, String password, double balance) {
? ? ? ?this.cardID = cardID;
? ? ? ?this.password = password;
? ? ? ?this.balance = balance;
? }
}
?
package com.by.test;
?
import com.by.entity.BankCard;
?
public class TestBankCard {
? ?public static void main(String[] args) {
? ? ? ?BankCard bc = new BankCard("628888888888888","411381",1000.0);
? ? ? /* bc.balance = 1000000000.0;
?
? ? ? ?System.out.println(bc.balance);
? ? ? ?System.out.println(bc.cardID);
? ? ? ?System.out.println(bc.password);*/
?
? ? ? ?//赋值
? ? ? ?bc.setCardID("627777777777777");
? ? ? ?//取值
? ? ? ?System.out.println(bc.getCardID());
?
? ? ? ?bc.setPassword("123456");
? ? ? ?System.out.println(bc.getPassword());
?
? ? ? ?bc.setBalance(100000.0);
? ? ? ?System.out.println(bc.getBalance());
?
? }
}
掌握
-
封装的步骤
-
getter、setter的区别
-
封装后的使用
2:继承
概念
将子类之间的共性进行抽取,生成父类.
在继承关系下,子类就可以默认拥有父类可别继承的内容
语法
class 子类类名 extends 父类类名{
? ?
}
public class Animal {
? ?public String name;
? ?public int age;
? ?public String color;
?
? ?public void eat(){
? ? ? ?System.out.println("吃饭");
? }
? ?public void sleep(){
? ? ? ?System.out.println("睡觉");
? }
?
}
public class Dog extends Animal{
?
}
public class Cat extends Animal{
?
}
规则
-
必须建立在is a关系之上
-
一个子类只能有一个直接父类 (单继承)
-
一个父类可以有多个直接子类
-
一个子类同时也可以是其他类的父类
-
子类中可以定义独有内容
-
父类无法访问子类的独有内容
-
子类可以继承拥有直接父类与间接父类中所有可被继承的内容
-
父类的私有内容子类无法直接继承访问
-
父类构造子类无法继承
子类的内存结构
-
子类的对象空间由
父类内容+独有内容
构成
父类封装
父类也是类,也应该按照要求进行属性的封装操作
package com.by.entity;
?
public class Animal {
? ?private String name;
? ?private int age;
? ?private String color;
?
? ?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 String getColor() {
? ? ? ?return color;
? }
?
? ?public void setColor(String color) {
? ? ? ?this.color = color;
? }
?
? ?public void eat(){
? ? ? ?System.out.println("吃饭");
? }
? ?private void sleep(){
? ? ? ?System.out.println("睡觉");
? }
?
}
使用
父类封装之后,子类将无法直接访问父类属性,必须通过调用getter()|setter()
的方式堆父类属性进行访问
public class Test2 {
? ?public static void main(String[] args) {
? ? ? ?Dog dog = new Dog();
? ? ?// dog.sleep();
? ? ? ?/*dog.name = "小黑";
? ? ? ?dog.age = 2;
? ? ? ?dog.color = "白色";*/
? ? ? ?dog.setName("小黑");
? ? ? ?dog.setAge(2);
? ? ? ?dog.setColor("白色");
? }
}
方法重写
-
又名方法覆盖
-
对从父类继承过来的方法进行方法体的重新书写,简称方法重写
规则
-
返回值类型、方法名、参数列表必须与父类保持一致
-
访问修饰符必须与父类相同或者更宽
-
不能抛出比父类更大或更多的异常
使用
子类进行方法重写之后,优先使用自身重写内容
父类的作用:
作为子类的共性抽取,解决子类之间的冗余问题
强制约束子类必须拥有某些特征和行为
有继承关系的对象创建过程
-
子类对象的构建
-
给父子类属性分配空间,赋默认值
-
给父类属性赋初始值
-
执行父类构造
-
给子类属性赋初始值
-
执行子类构造
super关键字
-
代表父类对象
super.
-
指明调用父类对象的属性或方法
super.属性名 super.方法名(实参)
-
无法调用父类的私有属性
super()
-
调用父类构造内容
使用
-
必须写在子类构造有效代码第一行
-
根据参数列表决定执行的是哪个父类构造
-
this()和super()不可同时显式存在
-
执行子类构造内容之前必定先执行父类构造内容
-
当子类构造中未显式调用父类构造时,默认存在无参的
super()
-
可以利用有参的super()直接在子类有参构造中给父类属性赋值
package com.by.entity; ? public class Animal { ? ?private String name; ? ?private int age; ? ?private String color; ? ? ?public Animal() { ? } ? ? ?public Animal(String name, int age, String color) { ? ? ? ?this.name = name; ? ? ? ?this.age = age; ? ? ? ?this.color = color; ? } ? ?//省略getter\setter ? } ? public class Dog extends Animal{ ? ?public Dog(){ ? ? ? ? } ? ? ?public Dog(String name, int age, String color) { ? ? ? ?super(name, age, color); ? } } public class Test4 { ? ?public static void main(String[] args) { ? ? ? ?Dog dog = new Dog("小黑", 2, "白色"); ? ? ? ?System.out.println(dog.getName()); ? ? ? ?System.out.println(dog.getAge()); ? ? ? ?System.out.println(dog.getColor()); ? } }
-
优化后的子类的有参构造:
访问修饰符 子类类名(父类的属性,独有的属性){ ? ?super(父类属性); ? ?this.独有属性名=独有属性名; ? ? ? }
访问修饰符
-
控制内容可被访问的范围
本类 | 同包 | 非同包子类 | 非同包非子类 | |
---|---|---|---|---|
private(私有的) | √ | |||
default(默认的) | √ | √ | ||
protected(受保护的) | √ | √ | √ | |
public(公开的) | √ | √ | √ | √ |
-
都可以修饰属性、方法(普通方法、函数、构造)
-
都不可以修饰局部变量
-
只有public和default可以修饰掌握
-
继承的语法
-
继承的规则
-
方法重写的规则
-
有继承关系的对象创建过程
-
super关键字和this关键字的区别
-
四个访问修饰符及其作用范围
3:多态
概念
父类类型引用可以指向不同的子类对象
语法
父类类名 引用名=new 子类类名(); 父类引用=子类对象;
使用
-
建立在继承关系之上
-
实际创建的是子类对象
-
优先执行子类内容
-
父类引用无法访问子类的独有内容
-
编译失败
-
编译器关注的是引用类型,解释器关注的是实际对象类型
-
左边决定都能做什么,右边决定谁来做
-
-
引用类型间类型转换
自动类型转换
大类型 引用名=小类型引用名|小类型对象;
-
父类是大类型,子类是小类型
强转类型转换
小类型 引用名=(小类型)大类型引用名;
//利用多态创建Dog对象 ? ? ? ?Animal a = new Dog(); ? ? ? ?//将父类引用a强转为Dog引用 ? ? ? ?Dog dog = (Dog) a; ? ? ? // Dog的引用.lookDoor(); ? ? ? ?dog.lookDoor();
-
只能转向原本指向的子类类型
Animal a = new Dog(); Cat cat = (Cat) a; 错误!!
-
编译不报错,运行报错
-
java.lang.ClassCastException:类型转换异常
-
-
无父子类关系的子类之间不可进行强转
Dog d = new Dog(); Cat cat = (Cat) d; 错误!!
-
编译报错
-
多态的使用场景
-
用于容器: 将容器类型声明为大类型,则容器内部可以存放不同的小类型对象
Animal[] as = {new Dog(), new Dog(), new Cat(), new Cat()}; ? ? ? ?//Animal as[0]=new Dog(); ? ? ? ?//遍历数组,调用吃饭方法 ? ? ? ?for (int i = 0; i < as.length; i++) { ? ? ? ? ? ?as[i].eat(); ? ? ? }
-
用于参数: 将方法形参声明为大类型,则实参可以传入不同的小类型对象
public static void main(String[] args) { ? ? ? ?method1(new Dog());//狗吃大骨头 ? ? ? ?method1(new Cat());//猫吃小鱼干 ? } ? ? ?//定义一个函数,传入参数,可以执行出"狗吃大骨头"或"猫吃小鱼干" ? ?public static void method1(Animal a) {//Animal a=new Dog()//Animal a=new Cat() ? ? ? ?a.eat(); ? }
-
用于返回值:将方法的返回值声明为大类型,则可以实际return不同的小类型对象
public static void main(String[] args) { ? ? ? ?//调用函数并接收返回值 ? ? ? ?Animal a= method2(10);//Animal a=new Dog() ? ? ? ?a.eat();//狗吃大骨头 ? ? ?// Dog d=(Dog)method2(10); ? ? } ? ?//定义一个函数,传入整型参数n,判断n的奇偶性,n为偶数返回Dog对象,n为奇数返回Cat对象 ? ?public static Animal method2(int n){//Animal=new Dog() ? ? ? ?if (n % 2 == 0) { ? ? ? ? ? ?return new Dog(); ? ? ? } ? ? ? ?return new Cat(); ? }
instanceof关键字
-
判断当前对象是否与指定类型兼容
-
结果为布尔类型
引用名 instanceof 类名
public static void main(String[] args) {
? ? ? ?Animal[] as = {new Dog(), new Dog(), new Cat(), new Cat()};
? ? ? ?method(as);
? }
? ?//定义一个函数,传入一个Animal类型的数组,要求如果是Dog对象,执行"看门",如果是Cat对象,执行"猫吃小鱼干"
? ?public static void method(Animal[] as){
? ? ? ?for (int i = 0; i < as.length; i++) {
? ? ? ? ? ?if (as[i] instanceof Dog) {
? ? ? ? ? ? ? ?//将当前元素的类型强转为Dog类型
? ? ? ? ? ? ? ?Dog dog = (Dog) as[i];
? ? ? ? ? ? ? ?dog.lookDoor();
? ? ? ? ? } else {
? ? ? ? ? ? ? ?as[i].eat();
? ? ? ? ? }
? ? ? }
? }
使用
-
子类对象可以被父类类型兼容
-
父类引用只能被所指向的子类类型兼容
-
子类类型无法兼容父类对象
public static void main(String[] args) {
? ? ? ?Dog d = new Dog();
? ? ? ?System.out.println(d instanceof Dog);//t
? ? ? ?System.out.println(d instanceof Animal);//t
?
? ? ? ?Dog jm = new JinMao();
? ? ? ?System.out.println(jm instanceof Dog);//t
? ? ? ?System.out.println(jm instanceof Animal);//t
?
? ? ? ?Animal a = new Dog();
? ? ? ?System.out.println(a instanceof Animal);//t
? ? ? ?System.out.println(a instanceof Dog);//t
? ? ? ?System.out.println(a instanceof Cat);//f
? ? ? ?System.out.println(a instanceof JinMao);//f
? }
多态的好处
-
减少代码冗余
-
将代码解耦合,提高代码扩展性
掌握
-
多态的概念
-
多态的使用
-
引用类型间的强转
-
多态的三个使用场景(用法)
-
instanceof关键字的作用和语法
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!