Java_笔记_多态_包_final_权限修饰符_代码块

news/2024/10/21 5:39:43/

封装:对象代表什么,就得封装对应的数据,并提供数据对应的行为。

一、多态:对象的多种形态。同类型的对象,表现出的不同形态。

1.多态的表现形式:父类类型 对象名称 = 子类对象;
学生形态 对象
Student s = new Student( );
人的形态 对象
Person p = new Student( );

2.多态的前提:
1)有继承/实现关系。
2)有父类引用指向子类对象。Fu f = new Zi( );
3)有方法的重写。

3.多态的优势:
1)在多态形式下,右边对象可以实现解耦合,便于扩展和维护。
Person p= new Student( );
p.work( ); //业务逻辑发生改变时,后续代码无需修改。
2)★定义方法的时候,使用父类型作为参数,可以接收所有子类对象,体现多态的扩展性与便利。

4.多态的弊端:不能调用子类的特有功能。
1)解决方法:变回子类类型。如果转成其他类类型,会报错。
2)引用数据类型的类型转换,有2种:自动类型转换;强制类型转换。
Person p = new Student(); //自动类型转换
Student s = (Student) p; //强制类型转换
3)强制类型转换,可以转换成真正的子类类型,从而调用子类独有功能。
转换类型与真实对象类型不一致会报错。
转换的时候用instanceof关键字进行判断。
4)代码:

//多态弊端
public class Test {public static void main(String[] args) {//创建对象Animal a = new Dog();//编译看左边,运行看右边a.eat();//多态的弊端//不能调用子类的特有功能//当调用成员方法的时候,编译看左边,运行看右边//在编译的时候会先检查左边的父类中有没有这个方法,如果没有直接报错//a.housekeeping();//多态弊端解决方法:把调用者a再变回子类类型/*int b = 10;byte c = (byte) b;*/Dog d = (Dog) a;d.housekeeping();//细节:转换时候不能转换成随意类型,否则报错/*Cat c = (Cat) a;c.catchMouse();*///实际开发中需要先判断类型是否可以转换/*if (a 是不是 狗){Dog d = (Dog) a;}else if (a 是不是 猫){Cat c = (Cat) a;}*//*if (a instanceof Dog) {Dog dog = (Dog) a;dog.housekeeping();} else if (a instanceof Cat) {Cat cat = (Cat) a;cat.catchMouse();} else {System.out.println("没有这个类型,无法转换");}*///★★★JDK14新特性//先判断a是否为Dog类型,如果是则强转成Dog类型,转换后变量名为dog//如果a不是Dog类型,结果直接为falseif (a instanceof Dog dog) {dog.housekeeping();} else if (a instanceof Cat cat) {cat.catchMouse();} else {System.out.println("没有这个类型,无法转换");}}
}class Animal {public void eat() {System.out.println("动物在吃东西");}
}class Dog extends Animal {@Overridepublic void eat() {System.out.println("狗吃骨头");}public void housekeeping() {System.out.println("狗在看家");}}class Cat extends Animal {@Overridepublic void eat() {System.out.println("猫吃小鱼干");}public void catchMouse() {System.out.println("猫在抓老鼠");}
}

5.多态的应用场景:
1)根据传递对象的不同,调用不同的show方法。
2)代码:

public class Person {private String name;private int age;public Person() {}public Person(String name, int age) {this.name = name;this.age = age;}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 void show() {System.out.println(name + "," + age);}
}
public class Administrator extends Person {@Overridepublic void show() {System.out.println("管理员的信息为" + getName() + "," + getAge());}
}
public class Student extends Person {@Overridepublic void show() {System.out.println("学生的信息为" + getName() + "," + getAge());}
}
public class Teacher extends Person {@Overridepublic void show() {System.out.println("老师的信息为" + getName() + "," + getAge());}
}
public class Test {public static void main(String[] args) {//创建三个对象,并调用register方法Student s = new Student();s.setName("皓恒");s.setAge(20);Teacher t = new Teacher();t.setName("瑞胤");t.setAge(30);Administrator admin = new Administrator();admin.setName("管理员");admin.setAge(35);register(s);//学生的信息为皓恒,20register(t);//老师的信息为瑞胤,30register(admin);//管理员的信息为管理员,35}//这个方法既能接收老师,又能接收学生,还能接收管理员//只能把参数写成这三个类型的父类public static void register(Person p) {p.show();}
}

6.多态调用成员的特点:
1)变量调用:编译看左边,运行也看左边。
2)方法调用:编译看左边,运行看右边。
3)代码:

public class Test {public static void main(String[] args) {//多态方式创建对象//Fu f = new Zi();Animal a = new Dog();//调用成员变量:编译看左边,运行也看左边//编译看左边:javac编译代码的时候,会看左边的父类中有没有这个变量,如果有编译成功,否则编译失败//运行也看左边:java运行代码的时候,实际获取的就是左边父类中成员变量的值//理解:用a去调用变量和方法,a是Animal类型,默认都会从Animal这个类去找//成员变量:在子类的对象中,会把父类的成员变量也继承下来System.out.println(a.name);//动物//调用成员方法//编译看左边:javac编译代码的时候,会看左边的父类中有没有这个方法,如果有编译成功,否则编译失败//运行看右边:java运行代码的时候,实际上运行的是子类中的方法//成员方法:如果子类对方法进行了重写,在虚方法表里会把父类的方法进行覆盖a.show();//Dog --- show方法}
}class Animal {String name = "动物";public void show() {System.out.println("Animal --- show方法");}
}class Dog extends Animal {String name = "狗";@Overridepublic void show() {System.out.println("Dog --- show方法");}
}class Cat extends Animal {String name = "猫";@Overridepublic void show() {System.out.println("Cat --- show方法");}
}

7.多态的综合练习

public class Animal {/*属性:年龄,颜色行为:eat(String something)(something表示吃的东西)*/private int age;private String color;public Animal() {}public Animal(int age, String color) {this.age = age;this.color = color;}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(String something) {System.out.println("动物在吃" + something);}
}
public class Cat extends Animal {public Cat() {}public Cat(int age, String color) {super(age, color);}/*行为:eat(String something)方法(something表示吃的东西)逮老鼠catchMouse方法(无参数)*/@Overridepublic void eat(String something) {System.out.println(getColor() + getAge() + "岁的猫狼吞虎咽" + something);}public void catchMouse() {System.out.println("猫抓老鼠");}
}
public class Dog extends Animal {/*1.定义狗类行为:eat(String something)(something表示吃的东西)看家housekeeping方法(无参数)*///空参构造//带全部参数的构造public Dog() {}public Dog(int age, String color) {super(age, color);}/*行为:eat(String something)(something表示吃的东西)看家housekeeping方法(无参数)*/@Overridepublic void eat(String something) {System.out.println(getAge() + "岁" + getColor() + "的伯恩山犬懒洋洋地躺在靠椅上吃" + something);}public void housekeeping() {System.out.println("狗在看家");}
}
public class Person {/*属性:姓名,年龄行为:keepPet(Dog dog,String something)方法功能:喂养宠物狗,something表示喂养的东西行为:keepPet(Cat cat,String something)方法功能:喂养宠物猫,something表示喂养的东西生成空参有参构造,set和get方法定义测试类(完成以下打印效果):keepPet(Dog dog,String something)方法打印内容如下:年龄为30岁的饲养员养了一只黑色的3岁的伯恩山犬 // 饲养员的行为3岁黑色的伯恩山犬懒洋洋地躺在靠椅上吃牛肉 //狗的行为keepPet(Cat cat,String something)方法打印内容如下:年龄为35岁的铲屎官养了一只棕色的6岁的猫棕色6岁的猫狼吞虎咽三文鱼罐头*/private String name;private int age;public Person() {}public Person(String name, int age) {this.name = name;this.age = age;}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;}/*keepPet(Dog dog,String something)方法打印内容如下:年龄为30岁的饲养员养了一只黑色的3岁的伯恩山犬 // 饲养员的行为3岁黑色的伯恩山犬懒洋洋地躺在靠椅上吃牛肉 //狗的行为keepPet(Cat cat,String something)方法打印内容如下:年龄为35岁的铲屎官养了一只棕色的6岁的猫棕色6岁的猫狼吞虎咽三文鱼罐头*//*//饲养狗public void keepPet(Dog dog, String something) {System.out.println("年龄为" + getAge() + "岁的" + getName() +"养了一只" + dog.getColor() + "的" + dog.getAge() + "岁的伯恩山犬");dog.eat(something);}//饲养猫public void keepPet(Cat cat, String something) {System.out.println("年龄为" + getAge() + "岁的" + getName() +"养了一只" + cat.getColor() + "的" + cat.getAge() + "岁的猫");cat.eat(something);}*///生成一个方法,能接收所有的动物//方法的形参,可以写这些类的父类Animalpublic void keepPet(Animal a, String something) {if (a instanceof Dog d) {System.out.println("年龄为" + getAge() + "岁的" + getName() +"养了一只" + d.getColor() + "的" + d.getAge() + "岁的伯恩山犬");d.eat(something);} else if (a instanceof Cat c) {System.out.println("年龄为" + getAge() + "岁的" + getName() +"养了一只" + c.getColor() + "的" + c.getAge() + "岁的猫");c.eat(something);} else {System.out.println("没有这种动物");}}
}
/*根据需求完成代码:
1.定义狗类
属性:
年龄,颜色
行为:
eat(String something)(something表示吃的东西)
看家housekeeping方法(无参数)2.定义猫类
属性:
年龄,颜色
行为:
eat(String something)方法(something表示吃的东西)
逮老鼠catchMouse方法(无参数)3.定义Person类//饲养员
属性:
姓名,年龄
行为:
keepPet(Dog dog,String something)方法
功能:喂养宠物狗,something表示喂养的东西
行为:
keepPet(Cat cat,String something)方法
功能:喂养宠物猫,something表示喂养的东西
生成空参有参构造,set和get方法4.定义测试类(完成以下打印效果):
keepPet(Dog dog,String something)方法打印内容如下:年龄为30岁的饲养员养了一只黑色的3岁的伯恩山犬 // 饲养员的行为3岁黑色的伯恩山犬懒洋洋地躺在靠椅上吃牛肉 //狗的行为
keepPet(Cat cat,String something)方法打印内容如下:年龄为35岁的铲屎官养了一只棕色的6岁的猫棕色6岁的猫狼吞虎咽三文鱼罐头5.思考:1.Dog和Cat都是Animal的子类,以上案例中针对不同的动物,定义了不同的keepPet方法,过于繁琐,能否简化,并体会简化后的好处?2.Dog和Cat虽然都是Animal的子类,但是都有其特有方法,能否想办法在keepPet中调用特有方法?*/
public class Test {public static void main(String[] args) {/*//创建对象并调用方法Person p1 = new Person("饲养员", 30);Dog d = new Dog(3, "黑色");p1.keepPet(d, "牛肉");Person p2 = new Person("铲屎官", 35);Cat c = new Cat(6, "棕色");p2.keepPet(c, "三文鱼罐头");*///创建饲养员的对象Person p = new Person("饲养员", 30);Dog d = new Dog(3, "黑色");Cat c = new Cat(6, "棕色");p.keepPet(d, "牛肉");p.keepPet(c, "三文鱼罐头");}
}

二、包

1.作用:
1)包就是文件夹。
2)用来管理各种不同功能的Java类,方便后期代码维护。
2.包名的规则:公司域名反写+包的作用。
需要全部英文小写,见名知意。com.company.domain

package com.company.domain

public class Student{
私有化成员变量
构造方法
成员方法
}
3.全类名/全限定名:包名+类名
com.company.domain.Student
4.使用其他类的规则
1)推演:
使用其他类时,需要使用全类名。

public class Test {public static void main(String[] args) {com.company.domain.Student s = new com.company.domain.Student();}
}
//导包
import com.company.domain.Student;public class Test {public static void main(String[] args) {Student s = new Student();}
}

2)使用同一个包中的类时,不需要导包。
3)使用java.lang包中的类时,不需要导包。
4)其他情况都需要导包。
5)如果同时使用两个包中的同名类,需要用全类名。

三、final:最终的,不可被改变的。

1.final修饰方法(了解):表明该方法是最终方法,不能被重写。
应用:不想被改变的规则方法。
2.final修饰类(了解):表明该类是最终类,不能被继承。
3.final修饰变量(掌握):叫做常量,只能被赋值一次。
1)常量:实际开发中,常量一般作为系统的配置信息,方便维护,提高可读性。
2)常量的命名规范:
单个单词:全部大写。
多个单词:全部大写,单词之间用下划线隔开。
3)★★★细节:
final修饰的变量是基本数据类型:变量存储的数据值不能发生改变。
final修饰的变量是引用数据类型:变量存储的地址值不能发生改变,对象内部的属性值可以改变。
4)核心:
常量记录的数据是不能发生改变的。
5)字符串是不可变的(private,final)。
6)常量的练习:
将学生管理系统中用户的操作改写为常量的形式。
Project Structure–Modules–Import Module–包里的iml配置文件
代码:

import java.util.ArrayList;
import java.util.Scanner;public class StudentSystem {private static final String ADD_STUDENT = "1";private static final String DELETE_STUDENT = "2";private static final String UPDATE_STUDENT = "3";private static final String QUERY_STUDENT = "4";private static final String EXIT = "5";public static void startStudentSystem() {ArrayList<Student> list = new ArrayList<>();loop:while (true) {System.out.println("------------欢迎来到学生管理系统-------------");System.out.println("1:添加学生");System.out.println("2:删除学生");System.out.println("3:修改学生");System.out.println("4:查询学生");System.out.println("5:退出");System.out.println("请输入您的选择:");Scanner sc = new Scanner(System.in);String choose = sc.next();switch (choose) {case ADD_STUDENT -> addStudent(list);case DELETE_STUDENT -> deleteStudent(list);case UPDATE_STUDENT -> updateStudent(list);case QUERY_STUDENT -> queryStudent(list);case EXIT -> {System.out.println("退出");System.exit(0);}default -> System.out.println("没有这个选项");}}}
}

四、权限修饰符

1.用来控制一个成员能够被访问的范围。
2.可以修饰成员变量,方法,构造方法,内部类。
3.有四种,作用范围由小到大(private < 空着不写(缺省/默认) < protected < public)
权限修饰符作用范围
权限修饰符

4.权限修饰符的使用规则:
1)实际开发中,一般只用private和public。
成员变量私有。方法公开。
2)特例:如果方法中的代码是抽取其他方法中的共性代码,这个方法一般也私有。

五、代码块

1.局部代码块(淘汰)
1)写在方法里的单独的大括号。节约内存。
2)提前结束变量的生命周期(已淘汰)。

public class Test {public static void main(String[] args) {//局部代码块(节约内存,淘汰){int a = 10;}//当代码执行到这里时,变量a就从内存中消失了System.out.println(a);}
}

2.构造代码块(逐渐淘汰)
1)写在成员位置的代码块。
2)作用:可以把多个构造方法中重复的代码抽取出来(不够灵活)。
3)执行时机:我们在创建本类对象的时候会先执行构造代码块再执行构造方法。
3.静态代码块(掌握)
1)格式:static{}
2)特点:需要通过static关键字修饰,随着类的加载而加载,并且自动触发,只执行一次。
3)使用场景:在类加载的时候,做一些数据初始化的时候使用(重点)。
4.代码:

public class Student {private String name;private int age;//执行时机://随着类的加载而加载的,并且只执行一次static {System.out.println("静态代码块执行了");}/*    //构造代码块{System.out.println("开始创建对象了");}public Student() {}public Student(String name, int age) {this.name = name;this.age = age;}*///构造方法里有重复
/*    //第一种方法public Student() {//调用本类其他构造this(null,0);}public Student(String name, int age) {System.out.println("开始创建对象了");this.name = name;this.age = age;}*///第二种方法public Student() {//调用方法}public Student(String name, int age) {//调用方法this.name = name;this.age = age;}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;}
}
import java.util.ArrayList;
import java.util.Scanner;public class App {//静态代码块,初始化static ArrayList<User> list = new ArrayList<>();static {//添加一些用户信息list.add("川研", "123", "312123505009081234", "12345677890");}public static void main(String[] args) {Scanner sc = new Scanner(System.in);while (true) {System.out.println("欢迎来到学生管理系统");System.out.println("请选择操作:1.登录 2.注册 3.忘记密码");String choose = sc.next();switch (choose) {case "1" -> login(list);case "2" -> register(list);case "3" -> forgetPassword(list);case "4" -> {System.out.println("谢谢使用,再见");System.exit(0);}//大括号不能省略default -> System.out.println("没有这个选项");}}}
}

http://www.ppmy.cn/news/2687.html

相关文章

[附源码]计算机毕业设计JAVA中小型艺术培训机构管理系统

[附源码]计算机毕业设计JAVA中小型艺术培训机构管理系统 项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; S…

真人踩过的坑,告诉你避免自动化测试入门常犯的10个错误

虽然从自己的错误中学习也不错&#xff0c;但从别人的错误中学习总是更好的。 作为一个自动化测试人员&#xff0c;分享常见的容易犯的10个错误&#xff0c;可以从中吸取教训&#xff0c;引以为鉴。 一、必要时才自动化 新人小王接到为Web应用程序自动化测试脚本的任务时&…

InnoDB_Buffer_Pool

说明 对于使用InnoDB存储引擎的表来说, 无论是用于存储用户数据的索引,还是系统数据,都是以页的形式存放在表空间(tablespace)中。所谓的表空间(tablespace),实际是InnoDB对一个或几个实际文件的抽象,最终还是存在磁盘上。当InnoDB处理客户端请求时,如果需要访问某个页的…

30分钟了解linux操作系统内核总结

【推荐阅读】 概述Linux内核驱动之GPIO子系统API接口 一篇长文叙述Linux内核虚拟地址空间的基本概括 轻松学会linux下查看内存频率,内核函数,cpu频率 纯干货&#xff0c;linux内存管理——内存管理架构&#xff08;建议收藏&#xff09; Linux 内核性能优化的全景指南&#xff…

【web课程设计】HTML+CSS仿QQ音乐网站

&#x1f389;精彩专栏推荐 &#x1f4ad;文末获取联系 ✍️ 作者简介: 一个热爱把逻辑思维转变为代码的技术博主 &#x1f482; 作者主页: 【主页——&#x1f680;获取更多优质源码】 &#x1f393; web前端期末大作业&#xff1a; 【&#x1f4da;毕设项目精品实战案例 (10…

9.javase_GUI(swing)

一.GUI (1)GUI是&#xff1a;用图形的方式&#xff0c;来显示计算机操作的界面。 (2)javax.swing包 在awt的基础上&#xff0c;建立的一套图形界面系统&#xff0c;提供了更多的组件&#xff0c;而且完全由Java实现。增强了移植性&#xff0c;属轻量级控件 组件&#xff1a;是具…

芒果改进YOLOv5系列:全网首发最新原创打造RepGhostNeXt结构,基于重参数化结构,实现硬件高效的RepGhost模块、打造全新YOLOv5检测器

💡该教程为改进进阶指南,包含大量的原创首发改进方式, 所有文章都是全网首发原创改进内容🚀💡本篇文章 基于 YOLOv5、YOLOv7等网络改进YOLO系列:全网首发最新原创打造RepGhostNeXt结构,基于重参数化结构,实现硬件高效的RepGhost 模块、打造全新YOLOv5检测器。重点:�…

SpringBoot自动配置的原理-@SpringBootApplication

文章目录1自动配置原理1.1 SpringBootConfiguration1.2.ComponentScan1.3 EnableAutoConfiguration2 为什么不使用 Import 直接引入自动配置类学完这篇文章&#xff0c;可以了解到 SpringBoot 自动配置原理1自动配置原理 SpringBootConfiguration 是一个组合注解&#xff0c;由…