Java查漏补缺(3)

继承·抽象类·接口·静态·权限 相关

this与super关键字

this的作用:

  1. 调用成员变量(可以用来区分局部变量和成员变量)
  2. 调用本类其他成员方法
  3. 调用构造方法(需要在方法第一行)

举个栗子:

public class Father {
String name; public Father() {
System.out.println("父类无参构造");
}
} public class Son extends Father{
String name; public Son() {
this("");
System.out.println("无参构造");
} public Son(String name) {
System.out.println("有参构造");
this.name = name;
} public void method(){
System.out.println(this);
// System.out.println(super);
System.out.println(super.name);
} public static void main(String[] args) {
Father f = new Son();
}
}
/* 输出:
父类无参构造
有参构造
无参构造
*/

  但实际上this还记录着调用当前方法的对象的地址值,super则没有。因此成员方法中还可以这么写:

public void method(){
System.out.println(this);
// System.out.println(super);//这样是不可以的
}

我们知道在构造方法中,会隐式地调用父类的构造方法:

public Son() {
// super();//即使不写,这里也会隐式调用
}

  但是当使用this调用本类中其他构造方法之后,该构造方法便不再调用父类的构造方法,因为调用的其他构造方法会调用父类构造方法。

  并且,由于this和super调用构造方法时需要在第一行,因此this和super不能共存。


  • 重写:子类中出现和父类一模一样的方法,需要注意的是编译器不允许子类方法的方法名和参数列表与父类相同,但是返回值不同的方法,也不允许权限修饰小于父类方法的子类方法,重写的好处是可以修改父类方法或对其进行补充。
  • 只要执行构造方法就会执行构造代码块和成员变量!!!不论构造方法在哪调用
  • 方法修饰权限:
    • public:无访问限制
    • protected :同包及其子类可访问(子类可跨包)
    • 默认:同包可访问
    • private:只能本类访问。
  • 发现个有趣的情况:当父类方法使用private修饰后,子类再出现和父类同名的方法不再报错,但是不能使用@Override注解,使用注解会报错,同时调用方法也会改变:
public class Test {
private void m1() {
System.out.println("test m1");
} public void m(){
System.out.println("Test");
} public static void main(String[] args) {
//注意这种情况是因为父类m1方法是私有的,
//被private修饰的方法不参与重写
Son son = new Son();
son.m1();//调用的是子类的m1方法
Test test = new Son();
test.m1();//调用的是父类的m1方法 //如果子类重写了父类方法,编译时以等号左边为参考,运行时以等号右边为参考
test.m();//实际调用的是son的方法,并且如果父类没有m方法这里会编译不通过
}
} class Son extends Test {
// @Override//此时这里不能添加重写注解,因为这时子类并不能访问父类的方法
public void m1() {
System.out.println("son m1");
} @Override
public void m() {
System.out.println("son");
}
}

看来父类方法使用private修饰后就完全和其他类没什么关系了。

  • 构造方法的隐式三步(已经加载了类):

    1. super(); 它是在调用自己的父类空参数的构造函数。

      1.2. 这里还有个非静态成员变量隐式赋值。
    2. 非静态代码块和非静态显示赋值(按顺序执行)
    3. 构造方法
  • 子类的构造方法会调用父类的构造方法,如果父类没有无参构造,则必须调用有参构造。

  • 抽象类:有抽象方法的类必须为抽象类,但是抽象方法可以不包含抽象方法(没什么意义就是了)。抽象方法可以用来提取子类的共性,提供代码的复用性,抽象方法设立的目的就是为了被继承,一个所有方法都是private的抽象方法是没有意义的。

  • 抽象类和接口的简单区别:抽象类的子类只能单独继承一个类,但是可以实现多个接口,抽象类更多的是描述该类是不是某类,而接口更多的是描述有没有该功能,贴个说的不错的博客,就不在这多赘述了。

  • 如果一个类A同时实现类接口B、C,并且B、C内有一模一样的方法,子类必须重写该方法,否则编译报错。并且,如果接口B、C内的方法名字和参数类型一样,但是返回值不一样,此时类A无法实现重写,也就是说这样无论如何都编译不过去

  • 如果一个类A继承父类B,实现了接口C,在B、C中存在同名同参方法,当B中的方法被public修饰时不会报错。在调用时会调用父类的方法而不是接口的方法感觉研究这个好像没什么意义

public interface C {
void method();
//default void method(){}
} public class B {
public void method(){ }
} public class A extends B implements C { }
  • 子类再继承抽象类或者实现接口之后,可以本类重写抽象方法,或者也变成抽象类让孙子类实现。

  • 接口中的抽象方法有默认修饰符public abstract。默认方法必须使用default修饰,存在默认修饰符public。子类可以重写默认方法,也可以不重写。

  • 静态成员变量与非静态成员变量的区别:

    1. 它们在内存中出现的时间不同:

      静态成员变量:它是在加载当前这个类的时候,就在方法区的静态区中存在。

      非静态成员变量:当创建这个类的对象的时候,随着对象的产生在堆中出现。
    2. 它们所在的内存区域不同:

      静态成员变量:在方法区的静态区中。

      非静态成员变量:堆内存中。
    3. 它们的初始化时间不同:

      静态成员变量:在类加载的时候就会初始化,类加载完成,变量已经初始化结束。

      非静态成员变量:它是在对象的创建过程中被初始化。
    4. 它们的生命周期不同:

      静态成员变量:它随着类的加载就在方法区的静态区中一直存在。直到jvm虚拟机关闭,类从方法区消失,静态成员变量才会消失

      非静态成员变量:它是随着对象的产生而存在,随着对象的消失就消失
  • 多态形式调用子类和父类同名成员变量时,会使用父类的变量;

  • final修饰引用类型时,该变量地址不能变,即该变量不能重新赋值。但是该引用对象内的成员变量是可以修改的。(就拿数组来说,被final修饰的数组是不能变的,但是数组里面的数是可以变的)

InstanceofisInstance()的区别:

两者使用起来结果没什么区别



具体区别为:

instanceof 是静态比较,是 Java 内置的比较运算符。instanceof 后面的类名在编译时就已知且固定了,即 对象 instanceof 类,该必须是已经存在的类名,不能是通过getClass()得到的类,不然编译都过不了。

isInstance() 是动态比较,是个方法。isInstance() 的左边可以在运行时决定,即可以这样对象A.getClass().isInstance(对象B),对象A可以作为参数被传进来,这样可以动态的看两个对象是否类型兼容。

具体用法:

public class Father {
} public class Son extends Father {
} Father father = new Father();
Son son = new Son();
System.out.println(son instanceof Father);//true
System.out.println(father.getClass().isInstance(son));//true

通过上例可以看到infaceof右边必须是已知类的类名,而isInstance()则可以通过两个对象比较其关系。


  • 对于静态成员变量和静态代码块,可以在静态代码块中执行一些初始化的操作。像这样:
public class Test {
public static List<String> list; static {
list = new ArrayList<>();
list.add("HelloWorld");
}
}

一个多态的程序运行顺序分析

public class Father {
private String s = "father"; public Father(){
m();//这里虽然是在父类中调用,但是子类重写之后仍然会调用子类的m方法
} public void m(){
System.out.println(s);
}
} public class Son extends Father {
String s2 = "son"; @Override
public void m() {
System.out.println(s2);
} public static void main(String[] args) {
Father f1 = new Son();//这个打印null,需要注意
f1.m();//子类方法
Father f2 = new Father();//这个打印father
}
}

  这里,我本来以为执行父类构造方法的时候,m方法是在父类调用的,因此会执行父类的m方法,此时s已经赋值,便会打印“Father”,但实际上却并非如此。需要注意的是,此时是多态形式实例化Son,并且m()已经被重写,因此即使在父类中调用,调用的仍然是子类的m()方法!,此时子类中s2并未赋值,因此打印null。

  假如不使用多态,直接构造父类对象,此时则调用父类的m方法。

  直接实例化子类或者将f1向下转型,调用m()时均为子类。


IDEA Ctrl + i 快速重写方法

Java查漏补缺(3)(面向对象相关)的更多相关文章

  1. Java查漏补缺

    1.自动转换按从低到高的顺序转换.不同类型数据间的优先关系如下: 低 ---------------------------------------------> 高 byte,short,ch ...

  2. Java 查漏补缺

    摘自<老马说编程> 计算机程序的思维逻辑 (4) - 整数的二进制表示与位运算 Java中不支持直接写二进制常量,比如,想写二进制形式的11001,Java中不能直接写,可以在前面补0,补 ...

  3. Java基础查漏补缺(2)

    Java基础查漏补缺(2) apache和spring都提供了BeanUtils的深度拷贝工具包 +=具有隐形的强制转换 object类的equals()方法容易抛出空指针异常 String a=nu ...

  4. Java基础查漏补缺(1)

    Java基础查漏补缺 String str2 = "hello"; String str3 = "hello"; System.out.println(str3 ...

  5. 20165223 week1测试查漏补缺

    week1查漏补缺 经过第一周的学习后,在蓝墨云班课上做了一套31道题的小测试,下面是对测试题中遇到的错误的分析和总结: 一.背记题 不属于Java后继技术的是? Ptyhon Java后继技术有? ...

  6. Entity Framework 查漏补缺 (一)

    明确EF建立的数据库和对象之间的关系 EF也是一种ORM技术框架, 将对象模型和关系型数据库的数据结构对应起来,开发人员不在利用sql去操作数据相关结构和数据.以下是EF建立的数据库和对象之间关系 关 ...

  7. 2019Java查漏补缺(一)

    看到一个总结的知识: 感觉很全面的知识梳理,自己在github上总结了计算机网络笔记就很累了,猜想思维导图的方式一定花费了作者很大的精力,特共享出来.原文:java基础思维导图 自己学习的查漏补缺如下 ...

  8. Django 查漏补缺

    Django 查漏补缺 Django  内容回顾: 一. Http 请求本质: 网络传输,运用socket Django程序: socket 服务端 a. 服务端监听IP和端口 b. 浏览器发送请求 ...

  9. CSS基础面试题,快来查漏补缺

    本文大部分问题来源:50道CSS基础面试题(附答案),外加一些面经. 我对问题进行了分类整理,并给了自己的回答.大部分知识点都有专题链接(来源于本博客相关文章),用于自己前端CSS部分的查漏补缺.虽作 ...

随机推荐

  1. GNS3 模拟icmp路由跟踪

    R1 : conf t int f0/0 no shutdown ip add 192.168.1.1 255.255.255.0 no ip routing end R2 f0/0: conf t ...

  2. jmeter抓取cnode网站token值

    前置条件:已经登录 1.线程组下面先添加HTTP信息头管理器 1.1 jmeter向服务器发送http请求时,需要验证 cookie的等设置信息给到服务器去识别,因此,在发送请求前,我们一般会把相关需 ...

  3. pyhton输出表格数据出现省略号?(教你很快解决)

    //2019.07.18 pandas是python提供的非常好用的数据分析模块,但是在使用pandas进行数据分析时,有时候需要查看打印的结果,当dataframe行数或者列数比较多的时候,打印结果 ...

  4. 九九乘法表的四种三角形排布方式(for循环以及while循环的互换)

    #region //右上 for (int i = 1; i <= 9; i++){ for (int j = 1; j <= 9; j++){ if (i > j){ Consol ...

  5. 【LeetCode】课程表 II

    [问题]现在你总共有 n 门课需要选,记为 0 到 n-1.在选修某些课程之前需要一些先修课程.例如,想要学习课程 0 ,你需要先完成课程 1 ,我们用一个匹配来表示他们: [0,1]给定课程总量以及 ...

  6. 云时代架构阅读笔记九——web应用存在的问题及解决办法

    web应用通常存在的10大安全问题 1.SQL注入 拼接的SQL字符串改变了设计者原来的意图,执行了如泄露.改变数据等操作,甚至控制数据库服务器, SQL Injection与Command Inje ...

  7. redis常用的命令行以及操作

    redis常用的命令行以及操作 转载酱紫人的理直气壮 最后发布于2018-07-30 17:00:41 阅读数 805  收藏 转载地址:https://blog.csdn.net/li_lening ...

  8. 一百零六、SAP的OOP面向对象编程,OO-ALV的简介

    面向对象编程,如图 基本概念: 1.对象(Object)是一个现实实体的抽象.一个对象可被认为是一个把数据(属性)和程序(方法)封装在一起的实体,这个程序产生该对象的动作或对它接受到的外界信号的反应. ...

  9. ELK 教程

    自从ELK首次推出以来,下载量达到了数百万次,是世界上最流行的日志管理平台.相比之下,Splunk - 该领域的历史领先者 - 宣布的客户总数才15000人. 章节 ELK 介绍 ELK 安装Elas ...

  10. hdu 3308 线段树,单点更新 求最长连续上升序列长度

    LCIS Time Limit: 6000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submis ...