1.继承可以使你创建一个类(父类),之后可以扩充该类为一个更加特定的类(子类)
public class Circle extends GeometricObject{
}
Circle为子类,也可称为次类、派生类、扩展类
GeometricObject为父类,也成为基类,超类
extends为继承关键字
2.注意
几个类派生出一个子类称为多继承
关键字super指代父类,可以用于
super();//调用父类无参构造
super(参数);//调用有参构造
使用super()或super(参数)必须出现在子类构造方法的第一行,是显式调用父类的构造方法的唯一方式
public class GeometricObject {
//定义父类
private String color;//颜色
private boolean filled;//是否填充
public GeometricObject() {
this("white", false);//调用重载的构造方法
}
public GeometricObject(String color, boolean filled) {
this.color = color;//this调用对象引用的隐藏数据域
this.filled = filled;
}
}
public class Circle extends GeometricObject {
//Circle类继承GeometricObject 类
private double radius;
public static final double PI = 3.14;
public Circle() {
this(1.0, "black", true);
}
public Circle(double radius, String color, boolean filled) {
super(color, filled);//调用父类构造方法,必须放在第一行
this.radius = radius;
}
}
构造一个类的实例时, 将会调用沿着继承链的所有父类的构造方法。 当构造一个子类的对象时, 子类构造方法会在完成自己的任务之前, 首先调用它的父类的构造方法。 如果父类继承自其他类, 那么父类构造方法又会在完成自己的任务之前,调用它自己的父类的构造方法。 这个过程持续到沿着这个继承体系结构的最后一个构造方法被调用为止。
下面这个例子是查资料得来的,更能反映构造方法链
public class Faculty extends Employee{
public Faculty(){
System.out.println("(3)Performs Faculty's tasks") ;
}
public static void main(String[] args){
Faculty fac=new Faculty();
}
}
class Employee extends Person {
public Employee(){
System.out.println("(2)Performs Employee's tasks");
}
}
class Person {
public Person(){
System.out.println("(1)Performs Person's tasks");
}
}
//运行结果
//(1)Performs Person's tasks
//(2)Performs Employee's tasks
//(3)Performs Faculty's tasks
子类中没有显式定义构造方法,默认无参构造被隐式调用,并默认调用父类的无参构造,然而父类中没有定义无参构造,因此无法编译成功
public class GeometricObject {
private String color;
private boolean filled;
public GeometricObject(String color, boolean filled) {
this.color = color;
this.filled = filled;
}
//父类中没有定义无参构造
}
public class Circle extends GeometricObject {
private double radius;
public static final double PI = 3.14;
//默认调用无参构造和父类的无参构造
}
所以:如果要设计一个可以被继承的类,最好提供一个无参构造方法避免程序设计错误
1.要重写一个方法,就要和父类定义一样的签名和返回值类型来对该方法进行定义
public class GeometricObject {
@Override
public String toString() {
//父类toString方法
return "GeometricObject [color=" + color + ", filled=" + filled + "]";
}
}
public class Circle extends GeometricObject {
@Override//只有父类的实例方法是可访问时才能被覆盖
public String toString() {
//子类重写父类toString方法,方法签名和返回值类型相同
return super.toString()+" radius:"+getRadius();//重写方法必须使用super.方法名 调用父类的方法
}
}
public static void main(String[] args) {
//测试
// TODO Auto-generated method stub
Circle circle2=new Circle(3.0,"black",true);
System.out.println(circle2.toString());//GeometricObject [color=black, filled=true] radius:3.0
}
与实例方法相同,静态方法也能被继承,但是静态方法不能被覆盖,如果父类重定义的静态方法在子类中被重写,那么父类中的静态方法将会被隐藏
2.重写与重载的区别
**重载:**相同的方法名不同的签名定义多个方法
**重写:**在子类中提供一个对方法的新的实现,签名和返回值类型必须相同
方法重写发生在因为继承而相关的不同类中
方法重载可以发生在通一个类中,也可以发生在由于继承而相关的不同类中
重写标注@Override
如果使用了标注但是却没有重写,就会报错
重写方法中必须使用super.function()调用父类的方法
3.Object类
java中所有的类都继承自Object类
1.多态意味着父类的变量可以指向父类的对象
2.每个子类的实例都是其父类的实例,反之不行
1.声明类型和实际类型
Object o=new GeometricObject();
//Object声明类型 GeometricObject实际类型
2.动态绑定是指可以沿着继承链的多各个中实现
3.引用变量的声明类型决定编译时匹配哪个方法,实际类型决定动态绑定方法的实现
public static void main(String[] args) {
// TODO Auto-generated method stub
printString(new Circle(3.0));//创建Circle的匿名对象
printString(new Rectangle("black", true, 5.0, 6.0));//创建Rectangle的匿名对象
}
public static void printString(GeometricObject go) {
//动态调用toString方法
System.out.println(go.toString());
//运行结果:
//GeometricObject [color=white, filled=false] radius:3.0
//GeometricObject [color=black, filled=true] width:5.0 high:6.0
1.对象的引用可以可以类型转换为另一对象的引用,称为对象转换
Object o=new Student();//向下转换
//但是 Student s=o; 错误,需要显式转换
Student s=(Student)o;//向上转换,显式
尝试显式转换时确保一个对象是另一个对象的实例,利用instancesOf关键字实现
public static void main(String[] args) {
// TODO Auto-generated method stub
GeometricObject[] go = {
new Circle(5.0), new Rectangle("black", true, 5.0, 6.0),
new GeometricObject("blue", true) };//创建一个GeometricObject类型的数组
for (GeometricObject i : go) {
//遍历数组中元素
if (i instanceof Circle) {
//i是否是Circle的实例
System.out.println(((Circle) i).getArea());//因为GeometricObject 类中没有getArea方法,所以要显式转换
} else if (i instanceof Rectangle) {
//i是否是Rectangle的实例
System.out.println(((Rectangle) i).getPrimeter());//因为GeometricObject 类中没有getPrimeter方法,所以要显式转换
} else {
//i是否是GeometricObject的实例
System.out.println(i.toString());
}
}
}
//运行结果:
//78.5
//22.0
//GeometricObject [color=blue, filled=true]
为什么没有一开始就定义为Circle类型或Rectangle类型呢?
是为了能够通用设计,把变量定义为父类,这样就可以接收任何子类型的值
2.对象成员访问运算符(.)优先于类型转换。所以要先转换在打点调用方法
例:((Rectangle) i).getPrimeter()
3.注意
转换基本类型会返回一个新的值,但是转换对象不回创建新的对象
Object o=new Circle();
Circle c=(Circle)o;
//o和c指向同一个对象
1.在子类中,使用签名equals(SomeClassName obj)(例如:equals(Circle c)重写equals方法是错误的,应该使用equals(Object obj))
@Override
public boolean equals(Object obj) {
if(obj instanceof Circle) {
//判断Circle是否是obj的实例
return this.radius==((Circle)obj).getRadius();//比较两个的半径是否相等
}
else
return this==obj;
}
1.Arraylist可以用于存储对象列表
2.可以存储不限个数的对象
3.ArrayList是一个泛型类,具有一个泛型类型E
4.语法
ArrayList<E> list=new ArrayList<E>();
//jdk1.7之后可以去掉这个E
5.方法
ArrayList类中包含添加、清除、是否包含、查找、删除、修改等方法,在
下文中会提及
6.数组和ArrayList的区别
数组 | ArrayList | |
---|---|---|
定义 | int[] array=new array[5] | ArrayList<> list=new ArrayList<>() |
引用 | array[index] | list.get(index) |
更新元素 | array[index]=b | list.set(index,b) |
返回大小 | a.length | list.size() |
添加新元素 | list.add() | |
插入新元素 | list.add(index,b) | |
删除一个元素 | list.remove(index)或list.remove(b) | |
删除所有 | list.clear() | |
排序 | java.util.Arrays.sort(array) | java.util.Collections.sort(list) |
ArrayList中存储的都是对象,所以要用基本类型的包装类型
ArrayList<int> list=new ArrayList<>();//错误
ArrayList<Integer> list=new ArrayList<>();//正确
注意
public static void main(String[] args) {
// TODO Auto-generated method stub
ArrayList<Integer> list = new ArrayList<>();
list.add(1);
list.add(2);
list.remove(1);
System.out.println(list);//[1]删掉的是下标所对应的元素
//如果就想删掉1 用用list.remove((Integer)1);
}
7.数组和数组列表之间的转换
public static void main(String[] args) {
// TODO Auto-generated method stub
String[] str= {
"hello","java","fun"};
ArrayList<String> list = new ArrayList<>(Arrays.asList(str));//将数组转为数组列表
System.out.println(list);//[hello, java, fun]
String[] str2=new String[list.size()];
list.toArray(str2);//将数组列表转为数组
for(String i:str2) {
System.out.print(i+" ");//hello java fun
}
}
8.求列表中最大和最小以及打乱列表
public static void main(String[] args) {
// TODO Auto-generated method stub
ArrayList<Integer> list = new ArrayList<>();
for(int i=0;i<10;i++) {
list.add(i);
}
System.out.println(java.util.Collections.max(list));//获取最大值 9
System.out.println(java.util.Collections.min(list));//获取最小值 0
java.util.Collections.shuffle(list);//打乱数组列表
System.out.println(list);//[5, 7, 4, 3, 8, 9, 1, 2, 0, 6]
}
1.一个类的受保护成员可以从子类中访问
2.允许子类访问父类的数据域和方法,但不允许非子类访问,使用protected关键字
3.可见性递增:
私有的(private)、默认的(default)、受保护的(protected)、全局的(public)
4.protected允许包内类和包外子类访问
5.子类可以重写父类中protected修饰的方法,但是不能削弱方法的访问性,只能增加。
1.一个被final修饰的类和方法都不能扩展
2.只有final可以用在方法的局部变量上
通过对本章的学习,我知道了父类和子类之间关系,学会使用super调用父类的构造方法和方法,一定记得放在第一句,学会了多态的含义(父类的变量可以指向子类的对象),知道了重写和重载的区别,知道了动态加载的原因,懂得了向上显式转换,向下转换和instanceof的用法,学会了ArrayList数组列表的方便,protected修饰符的用法以及使用final关键字修饰类和方法来防止扩展。
加油!第十二章待更……
文章浏览阅读3.4k次,点赞8次,收藏42次。一、什么是内部类?or 内部类的概念内部类是定义在另一个类中的类;下面类TestB是类TestA的内部类。即内部类对象引用了实例化该内部对象的外围类对象。public class TestA{ class TestB {}}二、 为什么需要内部类?or 内部类有什么作用?1、 内部类方法可以访问该类定义所在的作用域中的数据,包括私有数据。2、内部类可以对同一个包中的其他类隐藏起来。3、 当想要定义一个回调函数且不想编写大量代码时,使用匿名内部类比较便捷。三、 内部类的分类成员内部_成员内部类和局部内部类的区别
文章浏览阅读118次。分布式系统要求拆分分布式思想的实质搭配要求分布式系统要求按照某些特定的规则将项目进行拆分。如果将一个项目的所有模板功能都写到一起,当某个模块出现问题时将直接导致整个服务器出现问题。拆分按照业务拆分为不同的服务器,有效的降低系统架构的耦合性在业务拆分的基础上可按照代码层级进行拆分(view、controller、service、pojo)分布式思想的实质分布式思想的实质是为了系统的..._分布式系统运维工具
文章浏览阅读174次。1.数据源准备2.数据处理step1:数据表处理应用函数:①VLOOKUP函数; ② CONCATENATE函数终表:step2:数据透视表统计分析(1) 透视表汇总不同渠道用户数, 金额(2)透视表汇总不同日期购买用户数,金额(3)透视表汇总不同用户购买订单数,金额step3:讲第二步结果可视化, 比如, 柱形图(1)不同渠道用户数, 金额(2)不同日期..._exce l趋势分析数据量
文章浏览阅读3.3k次。堡垒机可以为企业实现服务器、网络设备、数据库、安全设备等的集中管控和安全可靠运行,帮助IT运维人员提高工作效率。通俗来说,就是用来控制哪些人可以登录哪些资产(事先防范和事中控制),以及录像记录登录资产后做了什么事情(事后溯源)。由于堡垒机内部保存着企业所有的设备资产和权限关系,是企业内部信息安全的重要一环。但目前出现的以下问题产生了很大安全隐患:密码设置过于简单,容易被暴力破解;为方便记忆,设置统一的密码,一旦单点被破,极易引发全面危机。在单一的静态密码验证机制下,登录密码是堡垒机安全的唯一_horizon宁盾双因素配置
文章浏览阅读7.7k次,点赞4次,收藏16次。Chrome作为一款挺不错的浏览器,其有着诸多的优良特性,并且支持跨平台。其支持(Windows、Linux、Mac OS X、BSD、Android),在绝大多数情况下,其的安装都很简单,但有时会由于网络原因,无法安装,所以在这里总结下Chrome的安装。Windows下的安装:在线安装:离线安装:Linux下的安装:在线安装:离线安装:..._chrome linux debian离线安装依赖
文章浏览阅读153次。中国发达城市榜单每天都在刷新,但无非是北上广轮流坐庄。北京拥有最顶尖的文化资源,上海是“摩登”的国际化大都市,广州是活力四射的千年商都。GDP和发展潜力是衡量城市的数字指...
文章浏览阅读3.3k次。前言spark在java使用比较少,多是scala的用法,我这里介绍一下我在项目中使用的代码配置详细算法的使用请点击我主页列表查看版本jar版本说明spark3.0.1scala2.12这个版本注意和spark版本对应,只是为了引jar包springboot版本2.3.2.RELEASEmaven<!-- spark --> <dependency> <gro_使用java调用spark注册进去的程序
文章浏览阅读4.8k次。汽车零部件开发工具巨头V公司全套bootloader中UDS协议栈源代码,自己完成底层外设驱动开发后,集成即可使用,代码精简高效,大厂出品有量产保证。:139800617636213023darcy169_uds协议栈 源代码
文章浏览阅读4.6k次,点赞20次,收藏148次。AUTOSAR基础篇之OS(下)前言首先,请问大家几个小小的问题,你清楚:你知道多核OS在什么场景下使用吗?多核系统OS又是如何协同启动或者关闭的呢?AUTOSAR OS存在哪些功能安全等方面的要求呢?多核OS之间的启动关闭与单核相比又存在哪些异同呢?。。。。。。今天,我们来一起探索并回答这些问题。为了便于大家理解,以下是本文的主题大纲:[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JCXrdI0k-1636287756923)(https://gite_autosar 定义了 5 种多核支持类型
文章浏览阅读2.2k次,点赞6次,收藏14次。原因:自己写的头文件没有被加入到方案的包含目录中去,无法被检索到,也就无法打开。将自己写的头文件都放入header files。然后在VS界面上,右键方案名,点击属性。将自己头文件夹的目录添加进去。_vs2013打不开自己定义的头文件
文章浏览阅读3.3w次,点赞80次,收藏342次。此时,可以将系统中所有用户的 Session 数据全部保存到 Redis 中,用户在提交新的请求后,系统先从Redis 中查找相应的Session 数据,如果存在,则再进行相关操作,否则跳转到登录页面。此时,可以将系统中所有用户的 Session 数据全部保存到 Redis 中,用户在提交新的请求后,系统先从Redis 中查找相应的Session 数据,如果存在,则再进行相关操作,否则跳转到登录页面。当数据量很大时,count 的数量的指定可能会不起作用,Redis 会自动调整每次的遍历数目。_redis命令
文章浏览阅读449次,点赞3次,收藏3次。URP的设计目标是在保持高性能的同时,提供更多的渲染功能和自定义选项。与普通项目相比,会多出Presets文件夹,里面包含着一些设置,包括本色,声音,法线,贴图等设置。全局只有主光源和附加光源,主光源只支持平行光,附加光源数量有限制,主光源和附加光源在一次Pass中可以一起着色。URP:全局只有主光源和附加光源,主光源只支持平行光,附加光源数量有限制,一次Pass可以计算多个光源。可编程渲染管线:渲染策略是可以供程序员定制的,可以定制的有:光照计算和光源,深度测试,摄像机光照烘焙,后期处理策略等等。_urp渲染管线