final关键字绝育的">final关键字 (绝育的)
特点
java">1. 修饰方法 作用 这个被修饰的方法不能被重写
2. 修饰变量 作用 修饰的基本数据类型的变量 不能被重新赋值
被final 修饰的 对象的地址不能 改变(不能重新指向)
3. 修饰类 作用 被修饰的类不能被继承
代码示例
public class Demo01 {
public static void main(String[] args){
Class A = new ClassA();
a.fun();
final ClassA a1 = new ClassA();
a1.num = 20 ;
a1.num = 30 ;
System.out.println(a1.num);
}
}
class ClassA {
int nun;
public void fun(){
System.out.println("我是 ClassA 的 fun方法" );
}
public void fun1(){
System.out.println("打开 手机 银行 取钱" );
}
}
class ClassB extends ClassA {
@Override
public void fun1(){
super .fun1();
}
}
java">final 修饰成员变量的时候 该成员变量必须有有效的初值
被final 修饰的变量 程序中不能被修改 相当于常量
使用场景:
一般会与public static 连用
常量命名规范: 纯大写 多个用下划线分开
代码示例
public class Demo02{
}
class ClassC{
public static final int MAX_VALUE = 10 ;
public void fun (final int i){
System.out .println(MAX_VALUE);
}
}
多态一种事物的多种形态">多态 :一种事物的多种形态
前提
1.类与类之间要产生联系 继承关系
2.要有方法的重写(没有方法的重写 多态 的意义不大)
3.核心:父类的引用指向子类的对象
举例
人(姓名 年龄 性别)的多种形态
婴儿(多30块骨头) 少年(早恋) 成年(智齿) 中年(更年期) 老年(痴呆症)
暮年(最后一口气) 死人
动物(出声) 名字 种类 介绍自己(方法)
狗(汪汪汪) 猫(喵喵喵) 牛(萌萌萌) 羊(咩咩咩)
水果 香蕉 苹果 橘子 菠萝
代码举例
public class Demo03{
public static void main (String[] args){
Cat cat = new Cat();
Animal animal = new Cat();
animal.Speak();
Animal animal2 = new Dog();
animal2.Speak;
}
}
class Animal{
private String name;
private int kind;
public Animal (){
}
public Animal (String name, String kind){
this .name = name;
this .kind = king;
}
public String getName (){
return name;
}
public void setName (String name){
this .name = name;
}
public String getKind (){
return kind;
}
public void setKind (String kind){
this .kind = kind;
}
public void speak (){
System.out .println("动物会发出叫声" );
}
public String toString (){
return "姓名" + name + "种类:" + kind;
}
}
class Cat extends Animal{
public Cat (){
}
public Cat (String name, String kind){
this .name = name;
this .kind = name;
}
public void speak (){
System.out .println("猫会喵喵叫" );
}
public String toString (){
return super.toString();
}
}
class Dog extends Animal{
public Dog (){
}
public Dog (String name, String kind){
this .name = name;
this .kind = kind;
}
public void speak (){
System.out .println("狗会汪汪汪地叫" );
}
public String toString (){
return super.toString();
}
}
多态内存分析">多态 内存分析
多态">测试多态
调用成员变量 和 成员方法 在内存中的表现
多态 调用成员变量时 简单记 编译和运行 都看等号左边(父类引用)
解释: 当子类继承父类之后,new一个子类对象的时候,由于子类对象继承了父类的对象,
所有子类内存中会有一部分的内存区域(称为A 区域)保存的是父类的成员变量,当父类
引用指向子类对象时,父类的引用会指向A 区域,寻找A 区域的内存变量,如果A 区域没有
这个变量,编译将会报错,所有运行时候看的是左边父类,打印的是父类中得变量
多态 调用成员方法时,会动态绑定 简单记编译看左边(父类)运行看右边(子类)
解释: 编译时Animal animal = new Cat(),这句编译时,只要子类继承了父类,
这句话就可以编译通过,但当调用子类的方法时,比如调用子类的toString()方法或者
调用子类自身特有的方法时,编译器会坚持父类中有没有该方法,如果父类中没有在调
用的子类的方法时,编译将报错,如果父类中有子类的该方法时,编译将通过,所有称之
为编译看左边
的却是子类中的重写方法,而不是父类中同名的方法,所有运行看右边,即子类,输出的
是子类方法中得内容
内存图:
代码示例
public class Demo04 {
public static void main(String[] args){
Father father = new Son();
System.out.println(father.num);
father.print();
}
}
class Father {
int num = 10 ;
System.out.println("我是父类中的print方法" );
}
class Son extends Father {
int num = 20 ;
System.out.println("我是子类中得print方法" );
}
多态的好处与弊端">多态 的好处与弊端
多态 的好处:
1. 代码维护性强(这条建立在继承的基础上)
2. 代码的扩展性强(核心好处)
多态 的弊端:
使用多态 声明的时候 无法直接调用子类的特有方法 只能通过向下转型后才可以
使用子类特有的方法
int num = 97 ;
char c = (char )num;
System.out .println(c);
代码举例
public class Demo05 {
public static void main(String[] args){
Person person = new PZ();
person.speak();
PZ pz = (PZ)person;
pz.hit();
}
}
class person {
public void speak(){
System.out.println("人类会说话" );
}
}
class PZ extends person {
@override
public void speak(){
System.out.println("洗脑 掏钱" );
}
public void hit(){
System.out.println("打到死为止, 不能轻易放弃" );
}
}
多态举例1">多态 举例1
* 需求:
* 武器类 打 挥舞武器
* 刀类 打 挥舞刀 — 砍人
* 练功 练刀
* 棍类 打 挥棍 —— 敲人
* 练棍 耍棍
* 封装一个创建刀的方法 在方法中调用挥舞刀方法
public class Demo06 {
public void fun(WuQi wuqi){
wuqi.play();
}
public static void main(String[] args){
fun(new Dao());
fun(new Gun());
Wuqi wq = new Dao();
if (wq instanceof Dao){
Dao dao = (Dao) wq;
wq.practise();
}
}
}
class WuQi {
public void play(){
System.out.println("挥舞武器" );
}
}
class Dao extends WuQi (){
public void play(){
System.out.println("挥舞刀 - 砍人" );
}
public void practise(){
System.out.println("练刀" );
}
}
class Gun extends WuQi (){
public void play(){
System.out.println("挥棍 -- 敲人" );
}
public void parct(){
System.out.println("刷棍" );
}
}
多态举例2">多态 举例2
需求
* 铁桶僵尸(zombie) 血量 方法:被打一次掉2血 直到被打死
* 帽子僵尸 血量 方法:被打一次掉5血 直到被打死
* 封装一个 打僵尸的方法
*/
public class Demo07{
public void practise (Zombie z){
z.play();
}
public static void main (String[] args){
practise(new TtZombie(40 ));
practise(new mZZombie(60 ));
}
}
class Zombie{
private int blood;
public int getBlood (){
return blood;
}
public void setBlood (int blood){
this .blood = blood;
}
public void play (){
System.out .println("打僵尸,被打一次要掉血,直到被打死" );
}
}
Class TtZombie extends Zombie{
public TtZombie (){
}
public TtZombie (int blood){
super(blood);
}
public void play (){
while (true ){
if (this .getBlood() <= 0 ){
System.out .println("铁通僵尸被打死了" );
break ;
}
this .setBlood(this .getBlood() - 2 );
System.out .println("铁通僵尸剩余血量为:" + this .getBlood);
}
}
}
class MzZombie extends Zombie{
public MzZombie (){
}
public MzZombie (int blood){
this .blood = blood;
}
public void play (){
if (this .getBlood() <= 0 ){
System.out .println("帽子僵尸被打死了" );
return ;
}
this .setBlood(this .getBlood() - 5 );
System.out .println("帽子僵尸的血量为:" + this .getBlood());
play();
}
}
多态举例3">多态 举例3
* 定义主板类
* 主板
* 启动方法
* 插卡方法(例如声卡 网卡 显卡 内存条)
* 播放音乐 关闭播放
* 上网 断网
public class Demo08{
public static void main (){
MainBoard mainboard = new MainBoard();
mainboard.run();
mainboard.insertCard(new MusicCard());
mainboard.insertCard(new NetCard());
}
}
class MainBoard{
public void run (){
System.out .println("电脑已经启动" );
}
public void insertCard (Card card){
card.start();
card.stop();
}
}
class card{
public void start (){
System.out .println("卡已经插入" );
}
public void stop (){
System.out .println("卡已经拔出" );
}
}
class MusicCard extends Card{
public void start (){
System.out .println("音乐已播放" );
}
public void stop (){
System.out .println("音乐已暂停" );
}
}
class NetCard{
public void start (){
System.out .println("网络已连接" );
}
public void stop (){
System.out .println("网络已断开" );
}
}