Java基础笔记(十六)——继承
继承
提取出一些共性特征,作为父类,子类就可以继承父类的这些开放成员,子类再添加自己独有的属性和方法。如果再有类具有这些共同特征,也可继承这个父类。
特点:1.利于代码复用 2.缩短开发周期
继承是一种类与类之间的关系。
使用已存在的类的定义作为基础建立新类。
子类(派生类)——|>父类(基类)
新类的定义可以增加新的数据或新的功能,也可以用父类的功能,但不能选择性地继承父类的特征(即继承全部开放特征)。
满足“A is a B”的逻辑关系。如:猫和狗都继承动物类,学生和老师都继承人类。
继承的实现(extends)
父类
class Animal{
//公共的属性和方法
}
子类,只能继承一个父类
class Dog extends Animal{
//子类特有的属性和方法
}
class Cat extends Animal{
}
子类可以访问父类非私有成员【把父类的非私有(private修饰但提供了getter/setter方法不是私有)成员(属性和方法)当自己的用】。
父类不可以访问子类特有成员(即时public也不行)。
方法重写&方法重载
先回顾一下方法重载
1.同一个类中
2.方法名相同,参数列表不同(参数顺序、个数、类型),与参数名无关。
3.与方法返回值类型,访问修饰符无关。
方法重写:子类也具有父类的方法,但实现的功能有所不同,需要重写。即与父类同名的方法。
1.有继承关系的子类中。
2.子类重写父类的方法。
3.返回值类型,方法名,参数列表(参数类型、顺序、个数)都有与父类继承的方法相同,与方法的参数名无关(参数名相同与否均可)。
注:返回值类型,可以是子类类型。父类方法的返回值是父类类型,子类重写方法时,其返回值类型既可以是父类类型,也可以是子类类型,但只能向下兼容,不能向上兼容,不能是Object类。
如:父类 public Animal create(){ return new Animal();}
子类 @Override
public Dog create(){ return new Dog();}
4.子类方法的访问修饰符的访问范围需要大于等于父类的访问范围。private<default<protected<public
当子类重写父类方法后,子类对象调用的是重写后的方法,子类定义与父类同名的方法,要重写;子类可以定义与父类重名的属性。
super:父类对象的引用
子类可以把父类的开放成员(属性和方法)当作自己的用,子类包括继承父类的方法和自己重写父类的的方法。在子类的方法中,调用其它其它成员方法,在包含父类方法以及重写父类的方法情况下,子类肯定是调用重写的方法,那么如果想要调用父类的方法,而不是重写的那个方法,可以用super关键字来调用。如:super.eat(); super.setAge(3); 父类的属性可以用super调用,或者子类直接用就行。假如父类有name属性,子类不再定义了,如果成员方法或构造方法中用name属性,可以直接用或者super.name。
当然了,如果父类的方法没有被重写,子类对象和子类方法中在调用父类方法时如同自己的一样,子类在调用父类的开放属性时也是同自己定义的一样去使用。
父类的构造方法不允许被继承,也就不允许被重写了。
在有继承关系的程序初始化顺序:
在Java中,当实例化对象时,对象所在类的所有成员变量首先要进行初始化,只有当所有类成员完成初始化后,才会调用对象所在类的构造函数创建对象。
父类静态成员——>子类静态成员——>父类对象构造——>子类对象构造
静态成员【静态变量(也就是static成员属性)和静态代码块】,其中访问修饰符不影响成员加载顺序,谁先谁后与书写位置有关。
假设静态变量在静态代码块前面:(如果出现位置相反,就反过来)
父类静态变量、父类静态代码块、子类静态变量、子类静态代码块、父类非静态变量(成员属性)、父类构造代码块、父类构造函数、子类非静态变量、子类构造代码块、子类构造函数。
(1)静态优先非静态,静态属于类加载,只初始化一次,非静态属于对象,随着对象的创建可能会初始化多次。
(2)父类优先于子类进行初始化。Object类是超类(顶级父类。
(3)成员变量按出现顺序进行初始化,即使在方法中,也在任何方法被调用前(包括构造方法)先初始化。
构造方法的调用必须放在构造方法里,子类构造(包括带参构造)默认调用父类无参构造方法,如果要调用父类带参构造,可以通过super(参)调用父类允许被访问的其它构造方法。super必须在子类构造方法中的第一行。如:super(name,month);
super小结:
代表父类引用。
-访问父类成员方法 super.print();
-访问父类属性 super.name;
-访问父类构造方法 super();
(1)子类的构造的过程中必须调用其父类的构造方法(一层一层往上找,直到Object类)。
(2)如果子类的构造方法中没写super,则系统默认调用父类的无参构造方法,没显式写无参构造的,系统默认提供。
(3)如果父类中写了带参构造却没写无参构造,在子类的构造方法中,又没写super(参),则编译出错。【因为父类写带参构造了,系统就不会再提供无参构造了,而子类不写super(参),就会默认去调用父类的无参构造去,找不到,就出错。】如果父类既写了无参构造又写了带参构造,子类的构造方法中不写super,默认调用父类无参构造,写了super();也是调用无参构造,写了super(参),调用带参构造。其中子类的构造方法包括带参构造和无参构造都符合上述说法,创建对象时调用哪个构造,哪个构造都要遵守上述规则。super();就是调用父类无参构造,可写可不写,super(参)是调用指定的父类的带参构造。
(4)使用super(); super(参); 必须放在子类构造方法中的第一行。
super&this
在构造方法(有参构造)中写this(); 是先调用同类中的无参构造,this();也必须写在第一行。所以构造方法间调用时,this与super不能共存。
this:当前类对象的引用
-访问当前类的成员方法
-访问当前类的成员属性
-访问当前类的构造方法
-不能在静态方法中使用
super:父类对象的引用
-访问父类的成员方法
-访问父类的成员属性
-访问父类的构造方法
-不能在静态方法中使用
Object类
-Object类是所有类的父类。
-一个类没有使用extends关键字明确表示继承关系,则默认继承Object类(包括数组)。
-Java中的每个类都可以使用Object中定义的方法。【Object类是java.lang包里的(String、System...),此包系统默认加载,不要手动import】
-Object类中的equals方法和"=="是一样的,看地址是否相同,即是否指向同一个对象。String类中重写了Object类中的equals方法,比较对象的内容是否相同。
public class TestOne {
public static void main(String[] args){
Animal one=new Animal("小one",2);
Animal two=new Animal("小one",2);
//equals测试:继承Object类中的equals方法时,比较的是两个引用是否指向同一个对象。
boolean flag=one.equals(two);
System.out.println("one和two的引用比较:"+flag);
System.out.println("one和two的引用比较:"+(one==two));
System.out.println("==============================");
//String类重写了Object类的equals方法,比较的是对象的内容是否相同
String str1=new String("hello");
String str2=new String("hello");
flag=str1.equals(str2);
System.out.println("str1和str2的引用比较:"+flag);
System.out.println("str1和str2的引用比较:"+(str1==str2));
}
} //运行结果
小one2岁
小one2岁
one和two的引用比较:false
one和two的引用比较:false
==============================
str1和str2的引用比较:true
str1和str2的引用比较:false
那如何比较两个对象的内容值?
需要重写Object类中的equals方法
在Animal类中重写equals方法,使得比较对象的内容
public boolean equals(Object obj){
if(obj==null) //如果传入的对象为空,防止出现NullPointerException
return false;
Animal temp=(Animal)obj; //把传入的对象obj强转成Animal类型
if(this.getName().equals(temp.getName())&&this.getAge()==temp.getAge()){
return true;
}
else
return false;
} //运行结果
one和two的引用比较:true
one和two的引用比较:false
==============================
str1和str2的引用比较:true
str1和str2的引用比较:false
在Animal类中重载equals方法,使得比较对象的内容,不用类型强制转换,直接传入Animal类型
public boolean equals(Animal animal){
if(animal==null)
return false;
if(this.getName().equals(animal.getName())&&this.getAge()==animal.getAge()){
return true;
}
else
return false;
} //运行结果
one和two的引用比较:true
one和two的引用比较:false
==============================
str1和str2的引用比较:true
str1和str2的引用比较:false
如果重写和重载这两段代码都放在Animal类中,主函数中对象调用的是后者,因为后者通过Animal类型参数重载了equals方法,对象调用时会自动定位类型匹配方法。
Object类中的toString方法
返回这个类的字符串表现形式:类名+@+地址哈希值
(1)输出对象名时,默认会直接调用类中的toString
(2)继承Object中的toString方法时,输出对象的字符串表现形式:类型信息+@+地址信息
(3)子类可以通过重写toString方法的形式,改变输出的内容以及表现形式
在测试类中
public class TestOne {
public static void main(String[] args){
Animal one=new Animal("小one",2);
System.out.println(one.toString());
System.out.println(one);
}
} //运行结果
Animal@26cbb7db
Animal@26cbb7db
在Animal类中重写toString方法
public class Animal { private String name;
private int age;
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public Animal(String name,int age){
this.name=name;
this.age=age;
System.out.println(name+age+"岁");
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String toString(){ //重写toString方法
return "昵称:"+this.getName()+";年龄:"+this.getAge();
}
} //运行结果
小one2岁
昵称:小one;年龄:2
昵称:小one;年龄:2
Java基础笔记(十六)——继承的更多相关文章
- Java 读书笔记 (十六) Java 继承
例: 开发动物类,其中动物分别为企鹅以及老鼠,要求如下: 企鹅: 属性(姓名,id), 方法(吃,睡,自我介绍) 老鼠: 属性(姓名,id), 方法(吃,睡,自我介绍) 企鹅类: public cla ...
- java基础第十六篇之多线程
1:线程的概念 进程(任务):一个正在运行的程序 进程的调度:CPU来决定什么时候该运行哪个进程 (时间片轮流法) 线程在一个应用程序中,同时,有多个不同的执行路径,是进程中的实际运作单位. 好处是提 ...
- Java基础之十六 数组
数组:可以创建并组装它们,通过使用整型索引值访问它们的元素,并且它们的尺寸不能改变. 16.1 数组为什么特殊 数组与其他种类的容器之间的区别有三方面:效率,类型和保存基本类型的能力. 数组是一种效率 ...
- 夯实Java基础(十六)——枚举类的使用
1.枚举类简介 枚举是仅容许特定数据类型值的有限集合.例如我们平时生活中星期一到星期日这七天就是一个特定的有限集合,一年四季的春夏秋冬也同样是的,它们都是枚举.枚举和我们数学中的集合非常相似,如果我们 ...
- java基础(十六)集合(三)
这里有我之前上课总结的一些知识点以及代码大部分是老师讲的笔记 个人认为是非常好的,,也是比较经典的内容,真诚的希望这些对于那些想学习的人有所帮助! 由于代码是分模块的上传非常的不便.也比较多,讲的也是 ...
- Java学习笔记十六:Java中的构造方法
Java中的构造方法 1.使用new+构造方法 创建一个新的对象: 2.构造方法是定义在Java类中的一个用来初始化对象的方法: 3.构造方法与类同名且没有返回值: 4.语法格式: public 构造 ...
- Java基础笔记(六)——进制表示、ASCII码和Unicode编码
Java中有三种表示整数的方法:十进制.八进制.十六进制. 八进制:以0开头,包括0~7的数字.如:int octal=020; //定义int型变量存放八进制数据 十六进制:以0x或0X开头,包括 ...
- 集合框架、泛型、迭代(java基础知识十六)
1.ArrayList存储自定义对象并遍历 此类的 iterator 和 listIterator 方法返回的迭代器是快速失败的:在创建迭代器之后,除非通过迭代器自身的 remove 或 add 方法 ...
- Java基础(十六)断言(Assertions)
1.断言的概念 假设确信某个属性符合要求,并且代码的执行依赖于这个属性. 断言机制允许在测试期间向代码插入一些检查语句,当代码发布时,这些插入的检查语句将会被自动地移走. 断言失败是致命的,不可恢复的 ...
- “全栈2019”Java第四十六章:继承与字段
难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java第 ...
随机推荐
- Struts2 - 配置文件中result 节点详解
每个 action 方法都将返回一个 String 类型的值, Struts 将根据这个值来决定响应什么结果. 每个 action 声明都必须包含有数量足够多的 result 元素, 每个 resul ...
- 数据库连接池(connection pool)
1.JDBC数据库连接池的必要性 在使用开发基于数据库的web程序时,传统的模式基本是按以下步骤: – 在主程序(如servlet.beans)中建立数据库连接. – 进行sql ...
- FJOI2016 神秘数
题目大意 给定长为$N$一个序列,每次询问一个区间,求最小的不能表示为由区间内若干个(可以是$0$个)数的和的非负整数. 考虑一个可重集合$S$,设抽取$S$中若干个数相加无法得到的最小非负整数为$A ...
- 1057 Stack (30)(30 分)
Stack is one of the most fundamental data structures, which is based on the principle of Last In Fir ...
- LG3533 [POI2012]RAN-Rendezvous
2791: [Poi2012]Rendezvous Time Limit: 25 Sec Memory Limit: 128 MBSubmit: 259 Solved: 160[Submit][S ...
- 洛谷【P1104】生日(冒泡排序版)
题目传送门:https://www.luogu.org/problemnew/show/P1104 题目很简单,我主要是来讲冒泡排序的. 所谓冒泡排序,流程如下: 每次确定一个\(rk\)(从\(n\ ...
- POJ3126Prime Path(BFS)
#include"cstdio" #include"queue" #include"cstring" using namespace std ...
- 2 ubuntu 16.04 安装Elastic Stack
一: 安装JAVA8 添加ppa sudo add-apt-repository ppa:webupd8team/java sudo apt-get update 安装oracle- ...
- 想要table表格垂直滚动,加点CSS即可
<style> /*设置 tbody高度大于400px时 出现滚动条*/ table tbody { display: block; height: 400px; overflow-y: ...
- WCF服务用户名密码访问
有2种方式, 第一直接在程序中指定用户名密码,配置调用 private void BtnSearch_Click(object sender, EventArgs e) { try { var cli ...