使用static修饰的成员变量是静态变量
如果一个成员变量使用了关键字static,那么这个变量不属于对象自己,而属于所在的类多个对象共享同一份数据
推荐写法:类.静态变量
,该写法可以直接观看出变量是静态变量;
不推荐写法:对象.静态变量
类.静态变量
一旦使用了static修饰的成员方法,那么就成为了静态方法。静态方法不属于对象,而属于类。
如果没有static关键字,那么必须首先创建对象,然后才能通过对象使用他;
如果有static关键字,那么不需要创建对象,直接通过类名就能使用它;
无论是成员变量还是成员方法。如果有了static关键字修饰,都推荐使用类名进行调用。
静态变量:类名称.静态变量;
静态方法:类名称.静态方法;
注意:
1、静态不能直接访问非静态;
- 内存中先有静态的内容,后有非静态的内容。类似与先人不知道后人,但后人知道先人。
2、静态方法中不能使用this
原因:this代指当前对象,谁调用方法,谁就是当前对象。
package com.one;
public class DemoStatic {public static void main(String[] args) {
Student one =new Student("章北海",35);
one.room="自然选择号";//正确写法但是不推荐
//写成对象名.静态变量,javac编译的时候会编译成`类.静态变量`
Student.room="蓝色空间号";//推荐写法,直接看出来room是静态变量
Student two =new Student("东方延续",35);
System.out.println(two.getName()+"是"+two.room+"舰长"+two.getId());//东方延续是自然选择号舰长,并未设置,但是会共享数据
System.out.println("===============================");
MyClass.mystatic();
MyClass myone= new MyClass();
myone.method();
}
}
```jaVA
package com.one;
public class Student {
private int id;
private String name;
private int age;
//如果一个成员变量使用了关键字static,那么这个变量不属于对象自己,而属于所在的类多个对象共享同一份数据
static String room;
private static int idCounter=0;//学号计数器,每当new了一个对象的时候计数器++
//生成全参的构造方法
public Student(String name, int age) {
this.name = name;
this.age = age;
this.id=idCounter++;
}
//生成无参的构造方法
public Student() {
idCounter++;
}
/生成对应的访问和设置函数/
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
}
package com.one
public class MyClass {
int num=0;
static int numstatic=1;
public static void mystatic(){
System.out.println("我是一个静态方法");
//System.out.println(this);//报错,静态方法中不能写this;
//System.out.println(num);//静态方法不能直接访问成员变量
System.out.println("静态方法可以直接访问静态变量"+numstatic);//静态方法可以直接访问静态变量
}
public void method(){
System.out.println("我是一个不同的成员方法");
System.out.println("成员方法可以直接访问成员变量"+num);
System.out.println("成员方法可以直接访问静态变量"+numstatic);
//成员方法可以直接调用静态方法不用写类名
mystatic();
}
}
特点;当第一次用到本类的时候,静态代码块执行唯一的一次
静态内容总是先于非静态加载,所以静态代码块比构造方法先执行
静态代码块的用途
静态代码块:
类{
static{
//静态代块的内容
}
}
public class Person {
static {
System.out.println("静态代码执行");
}
public Person(){
System.out.println("构造方法执行");
}
}
package com.one;
public class Demo1 {
public static void main(String[] args) {
Person one=new Person();
Person two=new Person();
/*console
静态代码执行
构造方法执行
构造方法执行*/
}
}
继承是多态的前提,如果没有继承就没有多态
继承主要解决的就是共性抽取
##### 图示
//在继承关系中,“子类就是一个父类”,也就是说子类可以被当做父类看待
//例如:父类是员工,子类是讲师,那么讲师就是一个员工;关系is-a
// 父类的格式就是普通类的定义格式;
package com.one;
public class Employee {
int num=100;
public void method(){
System.out.println("我是员工类中的的方法");
}
}
package com.one;
//继承的格式
public class Teacher extends Employee{
int num=200;
public void methodZi(){
//就近使用本类中的num,没有则想上寻找
System.out.println(num);
}
public void three(){
int num=300;
System.out.println("局部变量"+num);//局部变量300
System.out.println("本类成员变量"+this.num);//本类成员变量200
System.out.println("父类的成员变量"+super.num);//父类的成员变量100
}
}
package com.one;
/*
在父类的继承关系中,如果成员变量重名,则创建子类对象时,访问有两种方式
直接通过子类对象访问成员变量
等号左边是谁,就优先用谁,没有则向上找
间接通过成员方法访问成员变量
该方法属于谁,就优先用谁,没有则向上找
即:就近原则
* */
public class DemoExtends {
public static void main(String[] args) {
Teacher teacher= new Teacher();
teacher.method();//我是员工类中的的方法;执行了员工类中方法;
System.out.println(teacher.num);
teacher.methodZi();//200
teacher.methodFu();//100
}
}
//三种变量的使用方法
System.out.println("局部变量"+num);//局部变量300
System.out.println("本类成员变量"+this.num);//本类成员变量200
System.out.println("父类的成员变量"+super.num);//父类的成员变量100
重写(Override)
重载(Overload)
权限等级:public>protected>(default)>private
defualt不是关键字,而是什么都不写留空
##### 子类方法的权限必须要大于等于父类的权限
package cn.day03;
public class Fu {
public void method(){
System.out.println("父类的方法");
}
void sayhello(){
//默认权限等级是(default)
System.out.println("我是父类");
}
public Object showclass(){
return null;
}
}
package cn.day03;
public class Zi extends Fu{
@Override//本注解检测是不是有效的覆盖重写,可以不写,一般都会写上
public void method(){
System.out.println("子类的方法");
}
@Override
public void sayhello(){
System.out.println("我的权限等级大于(default)");
}
@Override
public String showclass(){
//String属于子类返回值小于等于父类烦人范围
return "HELLO WORLD";
}
}
package cn.day03;
public class DemoExtends {
public static void main(String[] args) {
Zi zi=new Zi();
zi.method();
String str=zi.showclass();
System.out.println(str);
}
}
/*console
子类的方法
HELLO WORLD
*/
子类构造方法中默认隐含的super()
调用,所以一定先调用父类构造,后执行子类的构造。
子类的构造可以通过super关键字调用父类的重载构造。
super父类构造调用,必须是子类构造方法的第一个语句。不能一个子类调用多个super构造。
package cn.day03;
public class Fu {
public Fu(){
System.out.println("父类构造方法");
}
public Fu(int num){
System.out.println("父类重载构造方方法");
}
}
package cn.day03;
public class Zi extends Fu{
public Zi(){
super(20);//调用父类重载的有参构造方法,必须写在构造方法的第一行;
System.out.println("子类构造方法");
}
}
package cn.day03;
public class DemoExtends {
public static void main(String[] args) {
Zi zi=new Zi();
}
}
/*
父类重载构造方方法
子类构造方法
*/
Java语言是单继承的
JAVA可以多重继承
java.lang.Object
一个父类的直接父类是唯一的,但是一个父类可以拥有多个子类
package demo.jc;
public class User {
private double money;
private String name;public User() {
}
public User(double money, String name) {
this.money = money;
this.name = name;
}
public void show(){
System.out.println("我是"+name+"我有"+money+"块钱");
}
public double getMoney() {
return money;
}
public void setMoney(double money) {
this.money = money;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
package demo.jc;
import java.util.ArrayList;
public class Manger extends User{
public Manger() {
}public Manger(double money, String name) {
super(money, name);
}
public ArrayList<Double> send(double totalmoney,int count){
//创建一个集合,用来存储红包金额
ArrayList<Double> redlist =new ArrayList<>();
//首先查看群主有多少钱
double leftMoney=super.getMoney();
if(totalmoney>leftMoney){
System.out.println("余额不足");
return redlist;//返回空集合
}
//扣钱,在重新设置余额
super.setMoney(totalmoney-leftMoney);
double avg=totalmoney/count;
double mod=totalmoney%count;
//除不开的余数放在最后一个红包中
/*count.fori*///直接生成for循环
for (int i = 0; i < count-1; i++) {
redlist.add(avg);
}
//最后一个红包设置大的金额
double last=avg+mod;
redlist.add(last);
return redlist;
}
}
package demo.jc;
import java.util.ArrayList;
import java.util.Random;
public class Member extends User{
public Member() {
}public Member(double money, String name) {
super(money, name);
}
public void recive(ArrayList<Double> list){
//使用random的匿名对象,使用size获取列表长度;设置好范围
int index=new Random().nextInt(list.size());
//使用remove从当前集合删除,并返回对应值;即获得抢到的红包,
double delta=list.remove(index);
double money=super.getMoney();
//原来金额加回去;
super.setMoney(delta+money);
}
}
package demo.jc;
import javax.xml.crypto.Data;
import java.util.ArrayList;
public class DemoMain {
public static void main(String[] args) {
Manger boss=new Manger();
Member employee1=new Member();
Member employee2=new Member();
Member employee3=new Member();
boss.setName("章北海");
boss.setMoney(100.0);
boss.show();
employee1.setName("东方延续");
employee1.show();
employee2.setName("丁仪");
employee2.show();
employee3.setName("褚岩");
employee3.show(); System.out.println("==================");
ArrayList<Double> list =boss.send(20,3);
employee1.recive(list);
employee2.recive(list);
employee3.recive(list);
employee1.show();
employee2.show();
employee3.show();
}
}
package cn.day03;
public class Zi extends Fu{
public Zi(){
super(20);//调用父类重载的有参构造方法,必须写在构造方法的第一行;
System.out.println("子类构造方法");
}
@Override//本注解检测是不是有效的覆盖重写
public void method(){
super.method();//调用父类的成员方法
System.out.println("==============="+super.num);//调用父类的成员变量;
System.out.println("子类的方法");
}
@Override
public void sayhello(){
System.out.println("我的权限等级大于(default)");
}
@Override
public String showclass(){
//String属于子类返回值小于等于父类烦人范围
return "HELLO WORLD";
}
}
用法
package cn.day03;
public class DemoZi extends Fu{
public DemoZi(){
//使用this后不在调用super()
this(20);
}
public DemoZi(int num){
System.out.println("我被调用了");
}
String str="Hello World";
public void saystr(){
bb();//普通也可以调用
//也可以使用this调用
this.bb();
System.out.println(this.str);
}
public void bb(){
System.out.println("bbbbbbbb");
}
}
如果父类的方法中不确定如何进行{}方法体的实现,那么这应该就是一个抽象方法.
举例图示
抽象类不能创建对象,创建会报错;
abstrace
修饰的类都不能创建对象,即使该类不包含抽象方法;抽象类中可以有构造方法,是供子类初始化父类成员时使用的;与普通类差别不大;
抽象类不一定包含抽象方法,包含抽象方法的类一定是抽象类;
抽象类的子类,必须重写所有的抽象方法,否则编译报错;除非子类也是抽象类;
package cn.day03;
/*
抽象方法:就是加上abstract关键字,然后去掉大括号直接分号结束。
抽象类:抽象方法所在的类,必须是抽象类才行。在class之前写上abstract即可;
即含有抽象方法类一定是抽象类;
使用抽象类和抽象方法:
1、不能直接创建new抽象类对象
2、必须使用一个子类来继承抽象父类
3、子类必须覆盖重写抽象类当中的所有抽象方法;
覆盖重写(实现):子类去掉抽象方法中的abstract关键字,然后补上大括号
4、创建子类对象使用;
* */
public abstract class DemoCx {
//这是一个抽象方法,代表吃东西,具体吃什么不知道(大括号中有什么内容,不确定);
public abstract void eat();
public abstract void sleep();
//普通成员方法
public DemoCx(){
System.out.println("抽象类的构造方法执行");
}
public void say(){
System.out.println("Hello World");
}
}
package cn.day03;
//抽象类的子类,必须重写所有的抽象方法,否则编译报错;除非子类也是抽象类
public abstract class Dog extends DemoCx{
@Override
public void eat() {
//重写父类的抽象方法
System.out.println("哈士奇吃雪!!!");
}
}
package cn.day03;
public class ErHa extends Dog{@Override
public void sleep() {
//直接父类已经实现了一个抽象方法;因此只要再实现另一个抽象方法就可以
System.out.println("哈士奇已经睡着了");
}
}
package cn.day03;
public class DeMu extends DemoCx{
public DeMu(){
System.out.println("德牧的构造方法执行");
}
//直接重写所有的抽象方法
@Override
public void eat() {}
@Override
public void sleep() {
}
}
package cn.day03;
public class DemoMain {
public static void main(String[] args) {
// DemoCx aa= new DemoCx() ;//错误写法抽象类不能直接new对象
// Dog dog=new Dog();//子类没有完全重写父类的构造方法因此也是抽象类
// dog.eat();
ErHa erha=new ErHa();
erha.eat();
erha.sleep();
System.out.println("======================");
DeMu demu=new DeMu();
demu.eat();
demu.sleep();
}
}
/*Console
抽象类的构造方法执行
哈士奇吃雪!!!
哈士奇已经睡着了
======================
抽象类的构造方法执行
德牧的构造方法执行
*/
接口是一种公共的规范标准;只要符合标准就可以通用;
图示
接口是一种引用数据类型;最重要的内容就是其中的抽象方法;
接口是多个类的公共规范;
定义接口的格式
public interface 接口名称{
}
//接口名称的命名规范与类名称一致;
接口中包含的内容
如果是java7(jdk1.7)
1.常量
2、抽象方法
如果是Java8(jdk1.8)
如果是Java9
使用步骤
1、接口不能直接使用,必须使用实现类来实现该接口;
格式
public class 实现类名称 implements 接口名称{}
//实现类名称命名通常采用`接口名字`+`impl`来命名
2、创建实现类对象进行使用
接口名字
+impl
来命名3、注意事项
如果实现类并没有覆盖重写接口中所有的抽象方法,那么这个实现类就必须是一个抽象类;
接口中不包含普通方法,因为不写关键字会有默认的public
+abstract
直接成为抽象方法;
接口当中定义抽象方法,修饰符必须是两个关键字:public abstract
这两个关键字可以选择性的省略不写
4、示例
package day04;
/*
* 在任何版本的Java中,接口都能定义抽象方法;
*
注意:
* 接口当中定义抽象方法,修饰符必须是两个关键字:public abstract
* 这两个关键字可以选择性的省略不写;
* */
public interface MyInterfaceAbs {//定义的是抽象方法
public abstract void method();
//省略关键字abstract
public void method1();
//省略关键字public
abstract void method2();
//省略关键字public和abstract
void method3();
/*以上三种省略关键字都属于抽象方法;熟练之后可以使用省略关键字的写法*/
}
//实现类
package day04;
//关键字implements
public class MyInterfaceImpl implements MyInterfaceAbs{@Override
public void method() {
System.out.println("第1个方法");
}
@Override
public void method1() {
System.out.println("第一个方法");
}
@Override
public void method2() {
System.out.println("第二个方法");
}
@Override
public void method3() {
System.out.println("第三个方法");
}
}
package day04;
public class DemoInterface {public static void main(String[] args) {
//实例化实现类的对象;
MyInterfaceImpl impl=new MyInterfaceImpl();
impl.method();
impl.method1();
impl.method2();
impl.method3();
}
}
从Java8开始,接口支持默认方法;
用途
格式
public default 返回值 方法名(){}
注意事项
编码示例
package day04;
public interface MyInterfaceAbs {
//定义的是抽象方法
public abstract void method();
//省略关键字abstract
public void method1();
//省略关键字public
abstract void method2();
//省略关键字public和abstract
void method3();
/*以上三种省略关键字都属于抽象方法;熟练之后可以使用省略关键字的写法*///添加一个默认方法
public default void say(){
System.out.println("Hello World");
}
public default void sayHello(){
System.out.println("我是接口的默认方法,现在还没有被重写");
}
}
package day04;
public class MyInterfaceImpl implements MyInterfaceAbs{
@Override
public void method() {
System.out.println("第1个方法");
}
@Override
public void method1() {
System.out.println("第一个方法");
}
@Override
public void method2() {
System.out.println("第二个方法");
}
@Override
public void method3() {
System.out.println("第三个方法");
}
@Override
public void sayHello(){
//重写接口的默认方法,也可以不重写
System.out.println("我重写了接口的默认方法");
}
}
package day04;
public class DemoInterface {
public static void main(String[] args) {
MyInterfaceImpl impl=new MyInterfaceImpl();
impl.method();
impl.method1();
impl.method2();
impl.method3();
System.out.println("========");
//直接调用,默认方法直接被实现类实现;
impl.say();
//调用覆盖后的默认方法
impl.sayHello();
}
}
格式:将默方法中的default
变换成static
即可;
接口名称.静态方法名称()
注意事项
示例
在上述接口中添加静态方法,并直接调用;
package day04;
public interface MyInterfaceAbs {
public static void sayStatic(){
System.out.println("我是接口的静态方法");
}
}
package day04;
public class DemoInterface {
public static void main(String[] args) {
MyInterfaceImpl impl=new MyInterfaceImpl();
impl.method();
impl.method1();
impl.method2();
impl.method3();
System.out.println("========");
//直接调用
impl.say();
//调用覆盖后的默认方法
impl.sayHello();
System.out.println("====================");
MyInterfaceAbs.sayStatic();
}
}
/*
第1个方法
第一个方法
第二个方法
Hello World
我是接口的静态方法
*/
从java9开始才支持私有方法
本人电脑装的是java8顾不做展示;使用方法和类中的私有方法使用相同;
接口中也可以定义成员变量
,但必须使用public static final
三个关键字进行修饰;
从效果上看这就是接口的常量;
格式
public static final 数据类型 常量名称=数据值;
注意事项
public static final
;不写这三个关键字,会默认添加;MY_CLASS
示例
package day04;
public interface MyInterfaceAbs {
//定义接口中的成员变量,即常量
public static final int MY_CLASS=6;
//省略关键字不写,效果相同
String SCHOOL_NAME="哔哩哔哩大学";
}
package day04;
public class DemoInterface {public static void main(String[] args) {
MyInterfaceImpl impl=new MyInterfaceImpl();
impl.method();
impl.method1();
impl.method2();
impl.method3();
System.out.println("========");
//直接调用
impl.say();
//调用覆盖后的默认方法
impl.sayHello();
System.out.println("====================");
MyInterfaceAbs.sayStatic();
System.out.println("====================");
//输出常量
System.out.println(MyInterfaceAbs.SCHOOL_NAME);
System.out.println(MyInterfaceAbs.MY_CLASS);
}
}
/*Consloe
第1个方法
第一个方法
第二个方法
第三个方法
========
Hello World
我重写了接口的默认方法
====================
我是接口的静态方法
====================
哔哩哔哩大学
6
*/
1、接口没有静态代码块和构造方法;
2、一个类的直接父类是唯一的,但一个类可以实现多个接口;
格式:
public class Myinterface implements MyinterfaceA,MyinterfaceB{
//覆盖重写所有的抽象方法
}
3、如果实现类的多个接口当中,存在重复抽象方法,那么只需要覆盖重写一次即可;
4、如果实现类没有覆盖重写所有接口的抽象方法,那么实现类就必须是一个抽象类;
5、如果实现类所实现的多个接口中,存在重复的默认方法,那么实现类一定要对冲突的默认方法进行覆盖重写;
6、一个类如果直接父类当中的方法,和接口中的默认方法发生了冲突;优先用父类中的方法;
接口A,B的代码
package day04;
public interface MyInterfaceA {public abstract void methodA();
public abstract void func();
public default void hand(){
System.out.println("欢迎来到,傻狗之够");
}
public default void func2(){
System.out.println("接口A的默认方法");
}
}
package day04;
public interface MyInterfaceB {public abstract void mthodB();
public abstract void func();
public default void func2(){
System.out.println("接口B的默认方法");
}
public default void sayhello(){
System.out.println("HelloWorld,接口B");
}
}
实现类的代码
package day04;
public class InterfaceImpl implements MyInterfaceA,MyInterfaceB{@Override
public void methodA() {
}
@Override
public void mthodB() {
}
//func方法是两个接口都有的抽象方法,只需要覆盖一次即可
@Override
public void func() {
}
//两个接口中都存在func2的默认方法,因此需要在实现类中进行覆盖重写一次
@Override
public void func2() {
System.out.println("我该执行谁的");
//不写谁都不调用,但是只要进行了覆盖重写,即使没有内容依然正确;
MyInterfaceB.super.func2();
}
}
package day04;
public class Fu extends FuO{
public void sayhello(){
System.out.println("Hello World,父类方法");
}
}
package day04;
public class Zi extends Fu implements MyInterfaceB{
//实现类既可以继承同时还可以实现接口;
@Override
public void mthodB() {}
@Override
public void func() {
}
}
主方法
package day04;
public class Demo2Interface {public static void main(String[] args) {
InterfaceImpl impl=new InterfaceImpl();
impl.func2();
System.out.println("=======================");
Zi zi =new Zi();
//直接父类的方法与默认方法冲突后,优先使用父类的方法,非直接父类效果一样
zi.sayhello();//Hello World,父类方法,
}
}
/*Console
我该执行谁的
接口B的默认方法
=======================
Hello World,父类方法
*/
类与类之间是单继承的关系,直接父类只有一个;
类与接口之间是多实现的,一个类可以实现多个接口
接口与接口之间是多继承的
注意事项
1、多个父接口当中的抽象方法如果重复,没关系。因为抽象方法没有方法体;
2、多个父接口当中的默认方法如果重复,那么子接口必须进行默认方法的覆盖重写,而且带着default关键字。
代码示例
父接口
package day04;
public interface MyInterfaceC {
public abstract void func();public abstract void funcC();
public default void sayhello(){
System.out.println("Hello World接口C");
}
public default void edg(){
System.out.println("edg夺冠了!");
}
}
package day04;
public interface MyInterfaceD {public abstract void func();
public abstract void funcD();
public default void sayhello(){
System.out.println("Hello World接口D");
}
}
子接口
package day04;
public interface MyInterface extends MyInterfaceC,MyInterfaceD{
//同时继承了C,D接口,而且C,D同时包含func();方法,但因为func()是抽象方法,所以没关系;
public abstract void mthod();//接口继承中抽象方法不用重写;
//C,D同时包含默认方法sayhello(),所以必须要重写sayhello方法,而且必须加上关键字default;
@Override
default void sayhello() {
MyInterfaceC.super.sayhello();
}
}
实现类
package day04;
public class FuO implements MyInterface{@Override
public void mthod() {
}
@Override
public void func() {
}
@Override
public void funcD() {
}
@Override
public void funcC() {
}
}
主方法
package day04;
public class Demo2Interface {public static void main(String[] args) {
InterfaceImpl impl=new InterfaceImpl();
impl.func2();
System.out.println("=======================");
Zi zi =new Zi();
//直接父类的方法与默认方法冲突后,优先使用父类的方法,非直接父类效果一样
zi.sayhello();//Hello World,父类方法,
System.out.println("=======================");
FuO aa =new FuO();
aa.edg();
}
}
/*
我该执行谁的
接口B的默认方法
=======================
Hello World,父类方法
=======================
edg夺冠了!
*/
extends继承和implements实现是多态性的前提
对象具有多态性
代码当中体现多态性就是一句话,父类引用,指向子类对象
格式
父类 对象名= new 子类();
接口 对象名 =new 实现类();
成员变量
成员方法:
new
对象的时候换成那个子类对象,等号左边调用方法都不会发生变化;向上转型:向上转型一定是安全的;
弊端:对象一旦向上转型,就无法使用子类特有的方法;
原来不是则会报转型错误的异常,因此一定要做转型判断 instanceof
//格式
if (obj instanceof Zi) {
Zi aa = (Zi) obj;
}
代码示例
package day05;
public class Fu {
public void func(){
System.out.println("父类方法");
}
public void Dad(){
System.out.println("伟大的父爱");
}
}
package day05;
public class Zi extends Fu {
@Override
public void func(){
System.out.println("子类方法");
}
public void vip(){
System.out.println("我是子类特有的方法");
}
}
package day05;
public class Dog extends Fu{
}
主方法
package day05;
public class DemoMutil {
//多态:创建对象的时候左侧是父类,右侧是子类
public static void main(String[] args) {
Fu obj = new Zi();
//同名优先使用子类的方法
obj.func();
//子类没有的向上寻找父类的方法
obj.Dad();
// obj.vip();//报错,无法使用子类特有的方法,因为使用多态后对象默认向上转型,因此无法使用,
//解决方法:将对象向下转型,注意:向下转型必须原来是 ,才能够进行向下转型;
// 语法格式
// 子类名称 对象名 =(子类名称)父类对象
//进行向下转型的判断,必须原来是,才能转换为原来的
if (obj instanceof Zi) {
Zi aa = (Zi) obj;
aa.vip();
}
//原来不是则会报转型错误的异常,因此一定要做转型判断 instanceof
if (obj instanceof Dog) {
Dog bb = (Dog) obj;
} else {
System.out.println("我没有通过验证,Obj原来不是Dog");
}
}
}
/*
子类方法
伟大的父爱
我是子类特有的方法
我没有通过验证,Obj原来不是Dog
*/
当使用final关键字修饰类的时候,该类不能有任何子类,父类依然正常
package day05;
// 当使用final关键字修饰类的时候,该类不能有任何子类,父类依然正常;
// 由于本类没有子类,因此本类中的方法无法被覆盖重写,但是该类依旧可以覆盖重写父类的方法
public final class MyClass {
public void dreadmd(){
System.out.println("该类不能被继承");
}
}
当final关键字用来修饰一个方法的时候,这个方法就是最终方法,也就是不能被覆盖重写;
注意
对于类、方法来说,abstract关键字和final关键字不能同时使用,因为矛盾;
格式
package day05;
public class FuFinal {public final void readself(){
System.out.println("此方法被final修饰了,不能被覆盖重写");
}
}
//错误代码展示
package day05;
public class ZiFinal extends FuFinal{//报错,无法覆盖重写父类中被final修饰的方法
// @Override
// public final void readself(){
// System.out.println("此方法被final修饰了,不能被覆盖重写");
// }
public abstract final void error(){
System.out.println("final关键字和abstract不能同时使用");
}
}
使用final修饰后,这个变量就不能修改
不可变
示例代码
package day05;
public class DemoFinal {
public static void main(String[] args) {
final int num=666;
//使用final修饰后,这个变量就不能修改
//一次赋值,终生不改
System.out.println(666);
//num=222;//错误写法不支持
//num=666;错误写法
//使用final只允许赋值一次,即使相同也不可以二次赋值 final int age;
age=18;//正确写法,唯一一次赋值,
/*****************/
System.out.println("============================");
//对于基本类型来说,不可变说的是变量中的数据不可变;
//对于引用类型来说,不可变说的是变量中的地址值不可变;
final Student stu =new Student("傻狗");
System.out.println(stu.getName());
stu.setName("哈士奇");//内容发生改变,但是地址值没有发生改变;
System.out.println(stu.getName());//哈士奇
}
}
对于成员变量来说,如果使用final关键字进行修饰,那么这个变量照样不可变;
由于成员变量具有默认值,所以用final之后必须手动赋值,不会再给默认赋值;
对于final的成员变量,要么使用直接赋值,要么通过构造方法赋值;二者选其一;
必须保证类当中所有重载的构造方法,都最终会对final的成员变量进行赋值;
示例代码
package day05;
public class Person {
// private final String name;//不会在默认赋值
//private final String name="傻狗";手动赋值
private final String name;public Person() {
name="二哈";
}
public Person(String name) {
this.name = name;
}
//以上两个构造方法都实现了对name的赋值;
public String getName() {
return name;
}
//使用final后不能在被修改
// public void setName(String name) {
// this.name = name;
// }
}
真累啊!
记录不易,转载请注明出处;
手机扫一扫
移动阅读更方便
你可能感兴趣的文章