java自学第3期——继承、多态、接口、抽象类、final关键字、权限修饰符、内部类
一.继承:
关键字extends
/*
定义一个父类:人类
定义父类格式:public class 父类名称{
}
定义子类格式:public class 子类名称 extends 父类名称{
}
*/
- 代码示范:
*要点:
1.子类中在main方法中创建父类对象可调用父类方法;
2.不加关键字直接访问本方法局部变量(可重名时区分);
3.使用this关键字访问本类成员变量(可重名时区分);
4.使用super关键字访问父类成员变量(可重名时区分);
5.如果存在方法的重名:父类与子类有重名方法:
——对象new的谁则优先调用谁的重名方法,没有则向上寻找;
前面介绍了成员变量、成员方法继承的访问特点,接下来是构造方法:
——子类构造方法(父类无参时)中有一个默认赠送的super()方法
——父类有参时,子类里调用super的()里传参,重载时谁对的上调用谁;
6.如果要更新修改父类方法,本着设计原则尽量不去直接修改正在使用的类,
则可以进行覆盖重写:格式:通过使用super关键字继承父类需要的方法。
@Override
方法外部相同(){
super.父类方法();
//这里添加新的内容
}
/*
小结super
super关键字作用:
示例:
public class demo06Super extends demo01people {
public void method1(){
System.out.println(super.num); //1.在子类成员方法中访问父类的成员变量
}
public void method2(){
super.methodChongMing(); // 2.在子类成员方法中访问父类的成员方法
}
public demo06Super(){
super(); //3.在子类的构造方法中访问父类的构造方法
}
}
*/
7.this关键字的作用小结:
this关键字的作用:
1.在本类的成员方法中访问本类的成员变量
2.在本类成员方法中访问本类的另一个成员方法
3.在本类的构造方法中访问本类的另一个构造方法:
(1)this(...)调用必须是构造方法的第一个语句,一个this;
(2)super和this两种构造调用不能同时使用
- 代码示范:
String name = "python";
public void method1(){
String name = "python";
System.out.println(name);//无关键字时直接访问本方法局部变量
System.out.println(this.name);//访问本类成员变量
System.out.println(super.num);//访问父类成员变量
this.method2();//访问本类另一个成员方法
}
8.最后,继承三大特点:
1.单继承:一个子类只有一个直接父类
2.多级继承:父类、子类、子类也可作父类再向下延伸,最上级为java.lang.object类
3.一个父类可以有多个子类
二、多态
1.多态性:父类引用指向子类对象
多态的一个用处:无论右边new的时候换成哪个子类对象,等号左边调用方法都不会发生变化
格式:
父类名称 对象名 = new 子类名称();
或者:
接口名 对象名 = new 实现类名称()。
2.成员方法:编译看左,运行看右;
成员变量:编译看左,运行也看左;实例变量不具备多态性.
代码示范:
//前面省略部分Zi类已经继承Fu类
public static void main(String[] args) {
Fu one = new Zi();//多态的写法
one.methodcommon();//重名时,成员方法优先使用子类(new谁先调用谁)。
one.fu1();//它的编译时类型为Fu,可以调用Fu中的方法
// one.zi1(); 该调用编译时会报错,因为它的编译时类型为Fu,无法调用zi1方法;
System.out.println(one.num);//优先看左边Fu类
Zi two = (Zi) one;//将父类对象还原成子类对象。
System.out.println(one instanceof Fu);//输出true,one可以做Fu类的实例对象
System.out.println(one instanceof Zi);//输出true,one可以做Zi类的实例对象
}
3.转型多态写法左父右子是正常的向上转型
4.向下转型:为了让对象调用子类方法(向上转型只能调用左边编译类型的父类方法)
左子类右父类,是一个还原的过程,将父类对象还原成子类对象,且不能向下转成别的子类。
格式: 子类名 对象名 = (子类名) 父类对象名; (后者也可以是接口)
Fu fu = new Fu();//向上转型创建父类对象
Zi two = (Zi) one;//将父类对象还原成子类对象。
5.强制向下转型时,判断前面的对象是否是后面类型的实例,是否可以成功转换,从而保证代码更加健壮。
格式: 对象 instanceof 类型
得到一个boolean值结果(true/false),判断前面的对象能否作为后面类型的实例
Zi two = (Zi) one;//将父类对象还原成子类对象。
System.out.println(one instanceof Fu);//输出true,one可以做Fu类的实例对象
System.out.println(one instanceof Zi);//输出true,one可以做Zi类的实例对象
三、接口
1.接口定义了某一批类需要遵守的规范。这就意味着接口里通常是定义一组公用方法。
2.接口是一种引用数据类型(类、接口、数组),注意其中的抽象方法。
3.接口可以继承接口,但不能继承类。
4.Java9 里可以有常量、抽象方法、默认方法、静态方法、私有方法。
5.备注:接口编译后生成的同样是.class的字节码文件
//格式
public interface 接口名称(首字母大写){
//抽象方法
}
- 接口里的成员变量只能是常量,必须用public static final修饰,可省略
//final即为不可改变
public static final int MAX_NUMBER = 20;
- 接口里的[普通方法]只能是抽象方法,public abstract可以省略
public abstract void out();
void getDate();
- 接口中的[默认方法]需要用default修饰
/*
当接口新添加方法时,新方法写为默认方法,则可以不去动其实现类,默认方法自动被其继承
默认方法同样可以被覆写。
*/
public default void print() {
foo();
System.out.println("默认方法调用3");
}
- 接口中定义[静态方法],需要用static修饰
public static void staticTest() {
System.out.println("静态方法!");
}
- 当俩默认方法中有重复内容时,抽取出来定义私有方法
//定义私有默认方法,给默认方法调用,但不应被实现类使用,所以权限为私有
private void foo() {
System.out.println("默认方法调用2");
}
//定义私有静态方法,给静态方法调用,但不应被实现类使用,所以权限为私有
private static void bar() {
System.out.println("bar私有静态方法");
}
}
- 接口不能创建实例,但能用于声明引用类型变量,且必须引用到实现类的对象;
- 一个实现类可以同时实现多个接口
//格式:
.public class 实现类名称 impliments{
//必须覆写接口中所有抽象方法;
},
- 在实现类(impliments)中进行接口的实现:
//
public class Demo01InterfaceImpl implements Demo01Interface,Demo02Interface {
//1,2接口都有out抽象方法,但只需覆写一次
@Override
public void out() {
System.out.println("抽象方法覆写!");
}
@Override
public void getDate() {
System.out.println("抽象方法覆写!");
}
@Override
public void print(){
System.out.println("冲突的默认方法也需要覆写!");//不冲突则不用覆写
}
}
- 然后在main类里创建实现类的对象,进行调用
public class Impliments {
public static void main(String[] args) {
//创建实现类的对象
Demo01InterfaceImpl ImplementationObject1 = new Demo01InterfaceImpl();
ImplementationObject1.getDate();
ImplementationObject1.out();
ImplementationObject1.print();//调用实现类里继承自接口的默认方法。
//接口里的静态方法只能通过接口名称直接调用。
Demo01Interface.staticTest();
//通过接口名直接访问常量。
System.out.println(Demo01Interface.MAX_NUMBER);
}
}
- 接口是多继承,一个接口可以有多个父接口。
- 多个父接口中的抽象方法如果存在重名,正常覆写;但默认方法重名需要带有default关键字覆写。
- 正常不冲突抽象方法不需要再覆写(实现类多个接口时也是如此)。
//接口的多继承,同样使用extends关键字
public interface Demo03InterfaceExtends extends Demo01Interface,Demo02Interface {
@Override
default void print() {
//覆写父接口的默认方法不能省略default关键字
}
}
四、抽象类
- 抽象方法:加上abstract关键字,去掉大括号,直接分号结束;
- 抽象类:抽象方法所在的类必须是抽象类,再class之前写上abstract即可
- 不能直接new抽象类对象,必须用一个子类来继承抽象父类
(抽象类对象调用的方法存在没有具体内容的方法体,因此没有意义) - 创建子类对象,不可创建抽象父类对象;
public abstract class demo01Abstract {
public abstract void method1();
public abstract void method2();
}
- 子类必须覆写抽象类中的所有抽象方法(去掉abstrat,补上大括号)。
(假设不全部覆写,对象调用的方法存在抽象方法,没有意义)
//使用extends继承抽象父类
public abstract class demo02Zi extends demo01Abstract {
//只覆写了一个抽象方法,没有将抽象方法全部覆写完,也就是说本子类还存在着继承下来的未覆写的抽象方法
//所以该类也同样是抽象类
@Override
public void method1() {
System.out.println("已经覆写第method1方法!");
}
}
//在这个子子类中已经将所有抽象方法全部覆写,所以该类不再是抽象类!
public class demo03Sun extends demo02Zi {
@Override
public void method2() {
System.out.println("已经覆写method2方法!");
}
}
- 最后在main类中的main方法里创建对象进行调用即可。
五、final关键字
- final表示它修饰的类、方法、成员变量、局部变量不可改变。
- final修饰的类不可被继承下去。无子类,不可被覆盖重写。
public final class 类名(){}
- final修饰的方法不可被覆盖重写。
public final void method(){}
- 类和方法不能同时使用final和abstract,二者矛盾。abstract表示抽象,是待定的;final表示最终的,是确定的。
- final修饰局部变量,若是基本数据类型的数值,则不可改变;若是引用数据类型,则地址值不可改变,但地址指向的对象的内容可以改变。
- final修饰成员变量,也不可变,但必须要进行手动赋值,成员变量加final后不允许再拥有默认值。
public final class Demo01Final {
public static void main(String[] args) {
int NUM = 1;
System.out.println(NUM);
NUM = 2;//可以改变
System.out.println(NUM);
final int NUM1 = 2;
// NUM1 = 3; 错误,NUM是确定的值,不可被改变。
}
}
六、权限修饰符
- 权限大小:
四种权限修饰符,访问权限从大到小:
public > protected > 空 > private
同一个类: yes yes yes yes
同一个包: yes yes yes no
不同包子类: yes yes no no
不同包非子类:yes no no no
七、内部类
一个外部类包含的一个嵌套的类,叫内部类。
分类:
1.成员内部类。
2.局部内部类(包含匿名内部类)。
- 注意:内部类可以无限制地访问外部类,外部类访问内部类需要内部类对象。
- 各个类对应可以使用的权限修饰符如下:
外部类:public/(default)
成员内部类:public.protect.(default).private
局部内部类:什么都没有,注意并不是(default) - 内部类定义示例:
public class main {
private String name = "成员变量";
//定义一个成员内部类
public class innerClass {
private String innername = "内部成员变量";
}
// 定义一个成员内部类内的成员方法
public void innermethod1() {
System.out.println("内部类方法");
System.out.println(name);
}
}
使用内部类的两种方式:
1.直接:在main方法中创建内部类对象:格式:
外.内 = new 外().内();
外部类名称.内部类名称 对象名 = new 外部类名称().new 内部类名称();
public static void main(String[] args) {
//直接创建内部类的对象。
InnerclassUsing.innerClass object = new InnerclassUsing().new innerClass();
object.innermethod1();
}
2.间接:在外部类的方法中,只用内部类,main只是调用外部类的方法,通过外部类方法访问内部类。
public class InnerclassUsing {
private String name = "成员变量";
//定义一个成员内部类
public class innerClass {
private String innername = "内部成员变量";
// 定义一个成员内部类的成员方法
public void innermethod1() {
System.out.println("内部类方法");
System.out.println(name);
}
}
public void outMethod() {
System.out.println("外部类成员方法");
// System.out.println(innername); 错误。
//通过匿名对象访问内部类变量和方法
System.out.println(new innerClass().innername);
//创建匿名对象并调用innermethod1方法。
new innerClass().innermethod1();
}
}
内部类的重名变量访问格式:
- 本方法: 空
- 本类成员变量:this.
- 外部类成员变量:外部类的名称.this.
public class Demo03CommonName {
//外部类成员变量
int NAME = 1;
public class innerClass{
//内部类成员变量
int NAME = 2;
public void method (){
//内部类局部变量
int NAME = 3;
System.out.println(NAME);//3,局部变量,就近原则。
System.out.println(this.NAME);//2,本类成员变量。
System.out.println(Demo03CommonName.this.NAME);//1,外部类的成员变量;
}
}
}
如果一个类定义在方法内部,那么这个类叫局部内部类。
局部内部类只能被当前所属的方法所使用,外部不可。
格式:
public class Localinnerclass {
String NAME = "外部成员变量";
public void method(){
//定义局部内部类
class localLinnerClass{
String ONE = "局部内部类成员变量";
public void nmethod2(){
System.out.println("局部内部类的成员方法");
System.out.println(ONE);
}
}
}
}
局部内部类,如果希望访问所在方法的局部变量,该变量应该满足【有效final】的条件
public class Demo04Final {
public void method1(){
//这里即使不写final的话,不去修改 也算是有效final [从java8开始]
final String NAME = "bilibili";
class LocalInnerclass{
public void localInnerMethod(){
//局部内部类内的方法访问所在类外部的方法的局部变量
System.out.println(NAME);
}
}
}
}
当接口是实现类只使用唯一一次时,可以使用匿名内部类
- 格式
接口名称 对象名 = new 接口名称(){
//这里进行抽象方法的覆写。
}; //别忘了结尾的分号
匿名内部类在创建对象的时候,只能使用唯一一次
匿名对象在使用方法时,只能使用唯一一次
匿名内部类是省略了(实现类/子类名称),而匿名对象则是省略了对象名称,二者不同。
//当实现类只使用一次时,可以使用匿名内部类的写法!
Anonymous obj6 = new Anonymous() {
//覆写匿名内部类里所有抽象方法!
@Override
public void method1() {
System.out.println("bilibili?");
}
@Override
public void method2(){
System.out.println("覆写method!");
}
};
obj6.method1();//打印内容
obj6.method2();
将类作为成员变量的写法
//定义一个武器类
public class Weapon {
private String itsname;//武器名称
private int attacknum;//武器攻击力
//无参构造方法
public Weapon() {
}
//全参方法
public Weapon(String itsname, int attacknum) {
this.itsname = itsname;
this.attacknum = attacknum;
}
//get名字
public String getItsname() {
return itsname;
}
//set名字
public void setItsname(String itsname) {
this.itsname = itsname;
}
//get攻击力
public int getAttacknum() {
return attacknum;
}
//set攻击力
public void setAttacknum(int attacknum) {
this.attacknum = attacknum;
}
}
//定义一个女武神类
public class Valkyrie1 {
private String name;//女武神之名
private Weapon weapon;//将武器类变为成员变量 交给女武神类
//女武神攻击方法
public void attack(){
System.out.println(name + "使用的" + weapon.getItsname() + "具有" + weapon.getAttacknum() +"点攻击力");
}
//无参构造
public Valkyrie1() {};
//全参
public Valkyrie1(String name, Weapon weapon) {
this.name = name;
this.weapon = weapon;
}
//get女武神名字
public String getName() {
return name;
}
//set女武神名字
public void setName(String name) {
this.name = name;
}
//get女武神武器
public Weapon getWeapon() {
return weapon;
}
//set女武神武器
public void setWeapon(Weapon weapon) {
this.weapon = weapon;
}
}
- 定义了女武神类和武器类后,在main方法中进行调用
Valkyrie1 valkyrie = new Valkyrie1();//创建一个女武神
valkyrie.setName("bronya"); //set女武神名字叫bronya
Weapon weapon = new Weapon("真理之钥",1000);//创建一把武器,并同时赋予名称和攻击力
// 也可以分开写: weapon.setItsname("真理之钥");//武器名字
// 也可以分开写: weapon.setAttacknum(1000);//武器攻击力
valkyrie.setWeapon(weapon);//将定义好的武器交给女武神
valkyrie.attack();//最后,女武神使用这把武器进行攻击
java自学第3期——继承、多态、接口、抽象类、final关键字、权限修饰符、内部类的更多相关文章
- 06 面向对象:多态&抽象类&接口&权限修饰符&内部类
多态: /* 多态(polymorphic)概述 * 事物存在的多种形态 多态前提 * a:要有继承关系. * b:要有方法重写. * c:要有父类引用指向子类对象. * 成员变量 * 编译看左边(父 ...
- 阶段1 语言基础+高级_1-3-Java语言高级_02-继承与多态_第6节 权限修饰符_6_四种权限修饰符
四种权限修饰符.从大到小 纵向再分成四种情况 同一个类 同一个类里面.private方式,可以访问到本类里面的 num成员变量 前面不写修饰符也能访问到 (default)就是不写的这种情况 受保护的 ...
- java——final、权限修饰符
final修饰类: final修饰成员方法: final修饰局部变量的时候: 对于基本类型来说,变量的数值不能改变 对于引用类型来说,变量的地址不能改变 final修饰成员变量的情况: 权限修饰符:
- 对于Java中权限修饰符的理解
老是把Java中权限修饰符给忘记,写一个博客加深印象吧 权限分为四个作用域:当前类,同一个包,其他包的子类,其他包的类. 首先要知道包的概念,Java中一个包是指一个package下的所有文件. pr ...
- -1-2 java 面向对象基本概念 封装继承多态 变量 this super static 静态变量 匿名对象 值传递 初始化过程 代码块 final关键字 抽象类 接口 区别 多态 包 访问权限 内部类 匿名内部类 == 与 equal
java是纯粹的面向对象的语言 也就是万事万物皆是对象 程序是对象的集合,他们通过发送消息来相互通信 每个对象都有自己的由其他的对象所构建的存储,也就是对象可以包含对象 每个对象都有它的类型 也就是 ...
- java基础课程笔记 static 主函数 静态工具类 classpath java文档注释 静态代码块 对象初始化过程 设计模式 继承 子父类中的函数 继承中的构造函数 对象转型 多态 封装 抽象类 final 接口 包 jar包
Static那些事儿 Static关键字 被static修饰的变量成为静态变量(类变量) 作用:是一个修饰符,用于修饰成员(成员变量,成员方法) 1.被static修饰后的成员变量只有一份 2.当成员 ...
- php面向对象 封装继承多态 接口、重载、抽象类、最终类总结
1.面向对象 封装继承多态 接口.重载.抽象类.最终类 面向对象 封装继承多态 首先,在解释面向对象之前先解释下什么是面向对象? [面向对象]1.什么是类? 具有相同属性(特征)和方法(行为)的一 ...
- Java三大特征:封装 继承 多态
内部类:成员内部类.静态内部类.方法内部类.匿名内部类. 内部类:定义在另外一个类里面的类,与之对应,包含内部类的外部类被称为外部类. 内部类的作用:(1)内部类提供了更好的封装,可以把内部类隐藏在外 ...
- lesson 4 再谈继承多态,抽象类和接口
再谈多态,抽象类和接口 上一次博客已经概念性的概述了继承多态,抽象类和接口,这次来具体的谈一谈他们之间的联系和需要注意的地方. 一.继承和多态:Inheritance (继承) & Polym ...
随机推荐
- svn 启动项目报错,项目被lock
问题描述 问题解决 (一)Eclipse SVN 插件处理 (二)SVN 客户端处理 (三)删除lock文件 问题描述 在使用开发工具开发项目时(如Eclipse),在做项目的中途,有时候Eclips ...
- python中字符串的翻转(方法总结)
Python翻转字符串(reverse string), 一共包含5种方法, 其中第一种最简单, 即步长为-1, 输出字符串; 方法如下 5种方法的比较: 1. 简单的步长为-1, 即字符串的翻转(常 ...
- NodeRED - 全局变量的使用笔记
NodeRED - 全局变量的使用笔记 global global.get(..) :获取全局范围的上下文属性 global.set(..) :设置全局范围的上下文属性 global.keys(..) ...
- Linux lsblk和df命令区别
lsblk 查看的是block device,也就是逻辑磁盘大小. df查看的是file system, 也就是文件系统层的磁盘大小
- Scala集合库、模式匹配和样例类
package com.yz8 import org.junit.Test class test { @Test def test: Unit = { val ints = List(1,5,7,6, ...
- Luogu T7468 I liked Matrix!
题目链接 题目背景 无 题目描述 在一个n*m 的矩阵A 的所有位置中随机填入0 或1,概率比为x : y.令B[i]=a[i][1]+a[i][2]+......+a[i][m],求min{B[i] ...
- Codeforces Round #646 (Div. 2) A. Odd Selection(数学)
题目链接:https://codeforces.com/contest/1363/problem/A 题意 判断是否能从 $n$ 个数中选 $x$ 个数加起来和为奇数. 题解 首先 $n$ 个数中至少 ...
- CodeForces - 1209D 并查集
题意: 有 n个不同的糖果,从 1到 n编号.有 k个客人.要用糖果招待客人.对于每个客人,这些糖果中恰有两个是其最爱.第 i个客人最爱的糖果编号是 xi和 y.将 k 个客人任意排列,他们按顺序去拿 ...
- __getattr__,__getattribute__和__get__的区别
dir(object) 列出对象的大多数属性 getattr(object, name) 从object对象中获取name字符串指定的属性 hasattr(object, name) 如果objec ...
- 牛客编程巅峰赛S1第11场 - 黄金&钻石 A.牛牛的01游戏 (模拟栈)
题意:有一个\(01\)串,两个相邻的\(0\)可以变成一个\(1\),两个相邻的\(1\)可以直接消除,问操作后的字符串. 题解:数组模拟栈直接撸,上代码吧. 代码: class Solution ...