java基础第8天
继承extends(也叫扩展)
多个类中存在相同的属性和行为时,将这些内容抽取到单独一个类中,那么多个类无需再定义这些属性和行为,只要继承那个类即可。
通过extends关键字可以实现类的继承
继承的案例
创建一个Person类,定义两个功能吃饭、睡觉,再创建学生类、教师类,继承Person类,再定义两个自己独有的功能
创建Persen类
public class Person {
public void eat(){
System.out.println("吃饭");
}
public void sleep(){
System.out.println("睡觉");
}
}
//创建子类学生类继承Person类
public class Student extends Person {
public void play(){
System.out.println("打游戏");
}
}
//创建Teacher类继承Person类
public class Teacher extends Person {
public void teach(){
System.out.println("教书");
}
}
//创建测试类,对继承进行测试
public class PersonExtends {
public static void main(String[] args) {
Student st = new Student();
st.eat(); //用学生类调用继承方法
st.play(); //调用自己的方法
Teacher t =new Teacher();
t.sleep();
t.teach();
}
}
继承的好处
提高了代码的复用性:多个类的相同成员可以放到一个类中
提高了代码的维护性:如果功能的代码需要修改,修改一处即可,继承的类中自动都被修改了
让类与类之间产生了关系,是多态的前提
Java中继承的特点
Java只支持单继承,不支持多继承
即一个类只能有一个直接父类,不可以有多个直接父类
正确写法:class Sub extends Demo{}
错误写法:class Sub extends Demo1,Demo2{}
Java支持多层继承
class A{}
class B extends A{}
class C extends B{}
例
//
public class Grandfather {
public void show(){
System.out.println("grandfather");
}
}
public class Father extends Grandfather {
public void method(){
System.out.println("father");
}
}
public class Son extends Father {
public void function(){
System.out.println("son");
}
}
//测试类
public class GrandfatherTest {
public static void main(String[] args) {
Son s = new Son();
s.function();
s.method();
s.show();
}
}
Java中继承的注意事项
子类只能继承父类中所有非私有的成员(成员变量、成员方法)
子类不能父类的的构造方法,但可以同super关键字去访问父类构造方法
不要为了部分功能去继承,如果有两个类A,B,只有他们符合A是B的一种或者B是A的一种,就可以考虑使用继承
继承中成员变量的关系
案列演示:
//创建父类定义成员变量
public class Field {
int num = 10;
public void method(){
System.out.println(num);
}
}
//创建子类继承父类,并定义与父类同名成员变量
public class FieldExtends extends Field {
int num = 15;
public void show(){
System.out.println(num);
}
//在子类中定义新的方法,在方法内再定义与父类成员变量同名变量
public void function(){
int num = 5;
System.out.println(num);
}
}
//测试类
public class FieldTest {
public static void main(String[] args) {
FieldExtends fe = new FieldExtends();
fe.show(); // 15
fe.function(); // 5
fe.method(); //10
}
}
通过案列可以知道在子类中访问一个变量的顺序
在子类方法的局部范围找,有就使用
在子类的成员范围找,有就使用
在父类成员范围找有就使用
如果找不到,就报错
super关键字
用法与this关键字类似
this 代表对本类对象的引用
super 代表父类存储空间的标识(可以理解为对父类对象的引用)
用法
访问成员变量
this.成员变量
super.成员变量(访问父类的成员变量,不能访问父类的private变量)
访问静态成员时,也可以用 父类名.静态成员
访问构造方法
this(...) super(...)
访问成员方法
this.成员方法() super.成员方法()
案列演示
//创建父类
public class FatherSuper {
int num = 10;
public FatherSuper(){
System.out.println("父类构造方法");
}
public void show(){
System.out.println("父类成员方法");
}
}
public class SonSuper extends FatherSuper {
int num = 15 ;
public SonSuper(){
System.out.println("子类构造方法");
}
public void method(){
System.out.println("子类成员方法");
}
public void function(){
int num = 5;
System.out.println(num); //打印方法内局部变量
System.out.println(super.num); //打印父类成员变量
System.out.println(this.num); //打印本类成员变量
super.show(); //调用父类成员方法
this.method(); //调用本类成员方法
}
}
测试类
public class SuperTest {
public static void main(String[] args) {
SonSuper ss = new SonSuper();
ss.function();
}
}
继承中构造方法的关系
子类中所有的构造方法默认都会访问父类中空参数的构造方法,除非显示使用super/this调用了父类或者本类的其他构造方法。
在类中对本类或者父类构造方法的调用,只能在构造方法中,不能在实例方法总中调用构造方法(更不能在类方法中调用构造方法)
注意构造方法不能递归调用
class A {
public A(int i){
this(1 ,2);
}
public A(int a ,int b){
this(2);
}
}
案例演示
//创建父类
public class A {
public A(){
System.out.println("父类空参构造");
}
public A(String name){
System.out.println("父类有参构造");
}
}
//创建子类继承父类
public class B extends A {
public B(){ //这一步默认执行了 super();调用了父类空参
System.out.println("子类空参构造");
}
public B(String name){
super(name); //调用父类有参构造方法
System.out.println("子类有参构造");
}
}
测试类
public class C {
public static void main(String[] args) {
B b = new B();
B b1 = new B("tom");
}
}
如果父类没有空参构造,子类的构造方法中就必须显式调用父类带参构造super(...);
super(…)或者this(…)必须出现在构造方法第一条语句上否则,就会有父类数据的多次初始化
方法重写
子类中出现和父类中一摸一样的方法声明,称为方法覆盖(Override)或重写(OverWrite)
使用特点
如果方法名不同就调用对应的方法
如果方法名相同最终使用的是自己的(使用子类的引用的时候,在多态情况下,使用父类的引用,则有可能调用的是父类静态方法)
方法重写的应用
当子类需要父类功能时,而功能主体子类有自己的特有的内容时,可以重写父类的方法,这样即沿袭了父类的功能,又定义了特有的内容。
方法重写是多态实现的条件
//首先创建 一个手机父类
public class PhoneF {
public void call(String name){ //定义一个方法
System.out.println("给"+name+"打电话");
}
}
//在创建一个手机子类继承父类
public class PhoneS extends PhoneF {
public void call(String name){ //同名同修饰词 对父类中的方法进行重写
super.call(name);
System.out.println("听天气预报"); //在继承父类之后在身再加的打印语句
}
}
//创建测试类
public class PhoneTest {
public static void main(String[] args) {
PhoneS ps = new PhoneS();
ps.call("Tom");
}
}
方法重写的注意事项
父类中私有的方法不能被重写,编译报错;
子类重写父类方法时,访问权限不能更低,编译报错;
子类重写父类方法时,返回值类型可以相同,也可以是父类返回值的子类型;
父类的实例方法(非静态方法),子类不能重新定义为静态方法
子类中的重写父类方法,按照重写的原则(访问权限不能变小,返回值类型同类或者为子类,方法名相同,形参列表相同);
子类想重写父类的方法,最好是让方法的签名一模一样;
final关键字
final关键字是最终的意思,可以修饰类,成员变量,成员方法 - 修饰类,类不能被继承(不能放在extends后面) - 修饰变量,变量将变成常量只能被赋值一次,不论是在子类还是本类中,都不能被修改(常量一般是大写字母表示 final int ONE = 1) - 修饰方法,方法不能被重写(子类只用使用权,没有修改权)
final修饰局部变量
在方法内部,该变量不可以被改变
在方法声明上,基本类型是这个参数的值不能被改变,引用类型,是这个参数只想的地址值不能被改变
总结
类中非static的final变量(实例final变量)可以在生命的时候赋值,如果声明的时候没有赋值的话,就必须在以下两个地方赋值,一个是构造代码块一个是构造方法中,如果这两个地方没有赋值,编译报错。
如果是static修饰的final变量的话,则只能在两个地方赋值,声明的时候,或者在静态代码块中。
多态(polymorphism)
某一个事物,在不同时刻表现出来的不同状态
在Java中,对一个事物的引用可以分成两种类型,一种是编译时的类型,一种是运行时的类型。 编译时的类型指的是声明这个变量时指定的类型;运行时类型指的是实际赋给这个变量的对象的类型。
若Student类继承自Person类,则下面的写法是正确的
Person p = new Student();
注意
父类引用不能调用子类特有的方法,因为使用了父类的引用,就代表站在父类角度来看待当前子类对象,只能看到从父类继承而来的特性,或者是子类重写的父类的方法。成员变量没有多态性,只能看到父类的成员变量。
多态中的成员访问特点
成员变量 编译看左边,运行看右边;
构造方法 创建子类对象的时候,访问父类的构造方法,对父类的数据进行初始化
成员方法 便宜看左边,运行看右边
静态方法 编译看左边,运行看右边
多态的前提条件
有继承关系
有方法重写
有父类引用指向子类对象
多态中成员访问特点
成员变量和静态方法没有多态性 只有被子类重写的成员方法才有多态性
java基础第8天的更多相关文章
- Java基础知识(壹)
写在前面的话 这篇博客,是很早之前自己的学习Java基础知识的,所记录的内容,仅仅是当时学习的一个总结随笔.现在分享出来,希望能帮助大家,如有不足的,希望大家支出. 后续会继续分享基础知识手记.希望能 ...
- [Java面经]干货整理, Java面试题(覆盖Java基础,Java高级,JavaEE,数据库,设计模式等)
如若转载请注明出处: http://www.cnblogs.com/wang-meng/p/5898837.html 谢谢.上一篇发了一个找工作的面经, 找工作不宜, 希望这一篇的内容能够帮助到大 ...
- 【JAVA面试题系列一】面试题总汇--JAVA基础部分
JAVA基础 基础部分的顺序: 基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法 线程的语法,集合的语法,io 的语法,虚拟机方面的语法 每天几道,持续更新!! 1.一个". ...
- 最适合作为Java基础面试题之Singleton模式
看似只是最简单的一种设计模式,可细细挖掘,static.synchronized.volatile关键字.内部类.对象克隆.序列化.枚举类型.反射和类加载机制等基础却又不易理解透彻的Java知识纷纷呼 ...
- java基础练习 字符串,控制流,日历,日期等
1,对基本控制流程的一些练习 package org.base.practice3; import org.junit.Test; /** * Created with IntelliJ IDEA. ...
- Java基础知识【下】( 转载)
http://blog.csdn.net/silentbalanceyh/article/details/4608360 (最终还是决定重新写一份Java基础相关的内容,原来因为在写这一个章节的时候没 ...
- Java基础知识【上】(转载)
http://blog.csdn.net/silentbalanceyh/article/details/4608272 (最终还是决定重新写一份Java基础相关的内容,原来因为在写这一个章节的时候没 ...
- java基础学习03(java基础程序设计)
java基础程序设计 一.完成的目标 1. 掌握java中的数据类型划分 2. 8种基本数据类型的使用及数据类型转换 3. 位运算.运算符.表达式 4. 判断.循环语句的使用 5. break和con ...
- Java基础加强之多线程篇(线程创建与终止、互斥、通信、本地变量)
线程创建与终止 线程创建 Thread类与Runnable接口的关系 public interface Runnable { public abstract void run(); } public ...
- java基础知识小总结【转】
java基础知识小总结 在一个独立的原始程序里,只能有一个 public 类,却可以有许多 non-public 类.此外,若是在一个 Java 程序中没有一个类是 public,那么该 Java 程 ...
随机推荐
- EA类图与代码同步
画了一段时间的图,愈发感觉到EA是一个强大的软件,而不不过一个绘图工具那么简单. . 随着学习时间的延长.如今写程序并不能像曾经一样随心所欲,想到什么就敲什么了,而是要先绘图(也就是理需求和思路的过程 ...
- 数据展现-百度js绘图
echarts:酷炫的绘图效果 http://echarts.baidu.com/examples/#chart-type-calendar
- [Axiom3D]第一个Axiom3D程序
Axiom3D程序的基本渲染流程 #region Namespace Declarations using System; using System.Linq; using Axiom.Core; u ...
- Python学习开发资源大全列表
1 机器学习和计算机视觉 Crab:灵活.快速的推荐引擎 gensim:人性化的话题建模库 hebel:GPU 加速的深度学习库 NuPIC:智能计算 Numenta 平台 pattern:Pytho ...
- spark mllib和ml类里面的区别
mllib是老的api,里面的模型都是基于RDD的,模型使用的时候api也是有变化的(model这里是naiveBayes), (1:在模型训练的时候是naiveBayes.run(data: RDD ...
- 【Lua】模块与包
定义: 从用户观点来看,一个模块就是一个程序库,可以通过require来加载(require用于使用模块,module用于创建模块),然后便得到了一个全局变量,表示一个table,这个 ...
- 数据挖掘-聚类分析(Python实现K-Means算法)
概念: 聚类分析(cluster analysis ):是一组将研究对象分为相对同质的群组(clusters)的统计分析技术.聚类分析也叫分类分析,或者数值分类.聚类的输入是一组未被标记的样本,聚类根 ...
- 3.8 Templates -- Actions
一.The {{action}} Helper 你的应用程序通常会需要一种方法来让用户用控件交互改变应用程序状态. 例如,你有一个显示blog post的模板,并支持用额外的信息扩展post. 可以使 ...
- VS异常--未找到与约束 ContractName Microsoft.VisualStudio.Language.Intellisense.IGlyphService RequiredTypeIdentity
早上打开项目的时候突然遇到这么个错误: ======================= 未找到与约束 ContractName Microsoft.VisualStudio.Language.Inte ...
- Linux /python --- zipinfo命令
Linux zipinfo命令用于列出压缩文件信息. 执行zipinfo指令可得知zip压缩文件的详细信息. zipinfo [-12hlmMstTvz][压缩文件][文件...][-x <范本 ...