尚硅谷Java入门哔哩哔哩274p-289p(2022.3.12)

2023-11-25 16:10

本文主要是介绍尚硅谷Java入门哔哩哔哩274p-289p(2022.3.12),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

274 super调用属性和方法

super关键字的使用

1.super理解为:父类的

2.super可以用来调用:属性,方法,构造器

3.super的使用:调用属性和方法

  3.1 我们可以在子类的方法或构造器中,通过使用“super.属性”或“super.方法”的方式,显式的调用父类中声明的属性或方法。但是,通常情况下,我们习惯省略“super.”

3.2 特殊情况:当子类和父类中定义了同名的属性时,我们要想在子类中调用父类中声明的属性,则必须显式的使用super.属性的方式,表明调用的的是父类中声明的属性

3.3 特殊情况:当子类重写了父类中的方法时,我们想在子类的方法中调用父类中被重写的方法时,则必须显式的使用super.方法的方式,表明调用的的是父类中声明的属性

public class Person{String name;int age;int id=1001;//身份证号public Person(){}public Person(String name){this.name=name;}public Person(String name,int age){this(name);this.age=age;}public void eat(){System.out.println("人:吃饭");}public void walk(){System.out.println("人:走路");}
}
public class Student extends Person{String major;int id=1002;//学号public Student(){}public Student(String major){this.major=major;}public void eat(){System.out.println("学生:多吃有营养的食物");}public void study(){System.out.println("学生:学习知识");}public void show(){System.out.println("name="+this.name+",age="+super.age);System.out.println("id="+this.id);System.out.println("id="+super.id);}
}
public class SuperTest{public static void main(String[] args){Student s=new Student();s.show();}

275 super调用构造器 

 4.super调用构造器

  4.1我们可以在子类的构造器中显式的使用super(形参列表)的方式,调用父类中声明的构造器

  4.2super(形参列表)的使用,必须声明在子类构造器的首行

  4.3我们在类的构造器中,针对于this(形参列表)或super(形参列表)只能二选一,不能同时出现

4.4在构造器的首行,没有显式的声明this(形参列表)或super(形参列表),则默认调用的是父类中空参的构造器:super()

4.5 在类的多个构造器中,至少有一个类的构造器中使用了super(形参列表),调用了父类的构造器

public class Student extends Person{String major;int id=1002;//学号public Student(){}public Student(String major){this.major=major;}public Student(String name,int age,String major){//this.name=name;//this.age=age;super(name,age);this.major=major;public void eat(){System.out.println("学生:多吃有营养的食物");}public void study(){System.out.println("学生:学习知识");}public void show(){System.out.println("name="+this.name+",age="+super.age);System.out.println("id="+this.id);System.out.println("id="+super.id);}
}
public class SuperTest{public static void main(String[] args){Student s=new Student();s.show();Student s1=new Student("Tom",21,"IT");s1.show();}
}

 276 子类对象实例化的全过程

 

 1.从结果上来看:(继承性)

    子类继承父类以后,就获取了父类中声明的属性或方法

    创建子类的对象,在堆空间中,就会加载所有父类中声明的属性

2.从过程上来讲

   

 当我们通过子类的构造器创建子类对象时,我们一定会直接或间接的调用其父类的构造器,进而调用父类的父类的构造器,直到调用了java.lang.Object类中空参的构造器为止。正因为加载过所有的父类的结构,所以才可以看到内存中有父类中的结构,子类对象才可以考虑进行调用

明确:虽然创建子类对象时,调用了父类的构造器,但是自始至终就创建过一个对象,即为new的子类对象 

public class InstanceTest{
}

277 继承和super课后练习

写一个名为Account的类模拟账户。该类的属性和方法如下图所示。
 * 该类包括的属性:账号id,余额balance,年利率annualInterestRate;
 * 包含的方法:访问器方法(getter和setter方法),
 * 返回月利率的方法getMonthlyInterest(),
 * 取款方法withdraw(),存款方法deposit()。
 

public class Account{private int id;private double balance;private double annualInterestRate;public Account(int id,double balance,double annualInterestRate){this.id=id;this.balance=balance;this.annualInterestRate=annualInterestRate;}public int getId(){return id;}public void setId(int id){this.id=id;}public double getBalance(){return balance;}public void setBalance(double balance){this.balance=balance;}public double getAnnualInterestRate(){return annualInterestRate;}public void setAnnualInterestRate(double annualInterestRate){this.annualInterestRate=annualInterestRate;}//返回月利率public double getMonthlyInterest(){return annualInterestRate/12;}//取钱public void withdraw(double amount){if(balance>=amount){balance-=amount;return;}System.out.println("余额不足");}//存钱public void deposit(double amount){if(amount>0){balance+=amount;}}
}

写一个用户程序测试Account类。在用户程序中,
 * 创建一个账号为1122、余额为20000、年利率4.5%的Account对象。
 * 使用withdraw方法提款30000元,并打印余额。再使用withdraw方法提款2500元,
 * 使用deposit方法存款3000元,然后打印余额和月利率。
 

public class AccountTest{public static void main(String[] args){Account acct=new Account(1122,20000,0.045);acct.withdraw(30000);System.out.println("您的账户余额为:"+acct.getBalance());acct.withdraw(2500);System.out.println("您的账户余额为:"+acct.getBalance());acct.deposit(3000);System.out.println("您的账户余额为:"+acct.getBalance());System.out.println("月利率为:"+(acct.getMonthlyInterest()*100)+"%");}
}

* 创建Account类的一个子类CheckAccount代表可透支的账户,该账户中定义一个属性overdraft代表可透支限额。
 * 在CheckAccount类中重写withdraw方法,其算法如下:
 * 如果(取款金额<账户余额),
 * 可直接取款
 * 如果(取款金额>账户余额),
 * 计算需要透支的额度
 * 判断可透支额overdraft是否足够支付本次透支需要,如果可以
 *         将账户余额修改为0,冲减可透支金额
 * 如果不可以
 *         提示用户超过可透支额的限额
 

public class CheckAccount extends Account{private double overdraft;//可透支限额public CheckAccount(int id,double balance,double annualInterestRate,double overdraft){super(id,balance,annualInterestRate);this.overdraft=overdraft;}public double getOverdraft(){return overdraft;}public void setOverdraft(double overdraft){this.overdraft=overdraft;}public void withdraw(double amount){if(getBalance()>=amount){//余额足够消费//getBalance()-=amount;setBalance(getBalance()-amount);//或super.withdraw(amount);}else if(overdraft>=amount-getBalance()){//透支额度加上余额足够消费overdraft-=(amount-getBalance());setBalance(0);}else{System.out.println("超过可透支限额!");}}
}

 写一个用户程序测试CheckAccount类。在用户程序中,
 * 创建一个账号为1122、余额为20000、年利率4.5%,
 * 可透支限额为5000元的CheckAccount对象。
 * 使用withdraw方法提款5000元,并打印账户余额和可透支额。
 * 再使用withdraw方法提款18000元,并打印账户余额和可透支额。
 * 再使用withdraw方法提款3000元,并打印账户余额和可透支额。
 

public class CheckAccountTest{public static void main(String[] args){CheckAccount acct=new CheckAccount(1122,20000,0.045,5000);acct.withdraw(5000);System.out.println("您的账户余额为:"+acct.getBalance());System.out.println("您的可透支余额为:"+acct.getOverdraft());acct.withdraw(18000);System.out.println("您的账户余额为:"+acct.getBalance());System.out.println("您的可透支余额为:"+acct.getOverdraft());acct.withdraw(3000);System.out.println("您的账户余额为:"+acct.getBalance());System.out.println("您的可透支余额为:"+acct.getOverdraft());}
}

 278 多态性的使用

public class Person{String name;int age;public void eat(){System.out.println("人:吃饭");}public void walk(){System.out.println("人:走路");}
}
public class Man extends Person{boolean isSmoking;public void earnMoney(){System.out.println("男人负责挣钱养家");}public void eat(){System.out.println("男人多吃肉,长肌肉");}public void walk(){System.out.println("男人霸气的走路");}
}
public class Woman extends Person{boolean isBeauty;public void goShopping(){System.out.println("女人喜欢购物");}public void eat(){System.out.println("女人少吃,为了减肥");}public void walk(){System.out.println("女人走路");}
}
public class PersonTest{public static void main(String[] args){Person p1=new Person();p1.eat();Man man=new Man();man.eat();man.age=25;man.earnMoney();//**************************************//对象的多态性:父类的引用指向子类的对象Person p2=new Man();Person p3=new Woman();//多态的使用:当调用子父类同名同参数的方法时,实际执行的是子类重写父类的方法--虚拟方法调用p2.eat();p2.walk();//     p2.earnMoney();}
}

1.理解多态性,可以理解为一个事物的多种形态

2.何为多态性

   对象的多态性:父类的引用指向子类的对象(或子类的对象赋给父类的引用) 

3.多态的使用:虚拟方法调用

有了对象的多态性之后,我们在编译期,只能调用父类中声明的方法,但在运行期,我们实际执行的是子类重写父类的方法

总结:编译,看左边;运行,看右边

4.多态性使用前提:

4.1 要有类的继承关系

4.2方法的重写

279 多态性使用举例

public class AnimalTest{public static void main(String[] args){AnimalTest test=new AnimalTest();test.func(new Dog());test.func(new Cat());}public void func(Animal animal){//Animal animal=new Dog();animal.eat();animal.shout()}//public void func(Dog dog){//     dog.eat();//     dog.shout();//}
}
class Animal{public void eat(){System.out.println("动物:进食");}public void shout(){System.out.println("动物:叫");}
}
class Dog extends Animal{public void eat(){System.out.println("狗吃骨头");}public void shout(){System.out.println("汪汪汪");}
}
class Cat extends Animal{public void eat(){System.out.println("猫吃鱼");}public void shout(){System.out.println("喵喵喵");}
}
//举例
class Driver{public void doData(Connection conn){//conn=new MySQLConnection/conn=newOracleConnection//规范的步骤去操作数据//conn.method1();}
}

280 多态性不适用于属性 

5.对象的多态性,只适用于方法,不适用于属性(编译和运行都看左边)

281 虚拟方法调用的再理解

 2.从编译和运行的角度看:
 * 重载,是指允许存在多个同名方法,而这些方法的参数不同。
 * 编译器根据方法不同的参数表,对同名方法的名称做修饰。
 * 对于编译器而言,这些同名方法就成了不同的方法。
 * 它们的调用地址在编译期就绑定了。Java的重载是可以包括父类和子类的,
 * 即子类可以重载父类的同名不同参数的方法。所以:对于重载而言,在方法调用之前,
 * 编译器就已经确定了所要调用的方法,这称为“早绑定”或“静态绑定”;
 * 而对于多态,只有等到方法调用的那一刻,解释运行器才会确定所要调用的具体方法,
 * 这称为“晚绑定”或“动态绑定”。
 * 
 * 引用一句Bruce Eckel的话:“不要犯傻,如果它不是晚绑定,它就不是多态。”
 */
//面试题:多态是编译时行为还是运行时行为?
//证明如下:
class Animal  {
 
    protected void eat() {
        System.out.println("animal eat food");
    }
}

class Cat  extends Animal  {
 
    protected void eat() {
        System.out.println("cat eat fish");
    }
}

class Dog  extends Animal  {
 
    public void eat() {
        System.out.println("Dog eat bone");

    }

}

class Sheep  extends Animal  {
 
    public void eat() {
        System.out.println("Sheep eat grass");

    }
 
}

public class InterviewTest {

    public static Animal  getInstance(int key) {
        switch (key) {
        case 0:
            return new Cat ();
        case 1:
            return new Dog ();
        default:
            return new Sheep ();
        }

    }

    public static void main(String[] args) {
        int key = new Random().nextInt(3);

        System.out.println(key);

        Animal  animal = getInstance(key);
        
        animal.eat();
         
    }

}

 285 向下转型的过程

public class Person {String name;int age;public void eat(){System.out.println("人,吃饭");}public void walk(){System.out.println("人,走路");}}
public class Man extends Person{boolean isSmoking;public void earnMoney(){System.out.println("男人负责工作养家");}public void eat() {System.out.println("男人多吃肉,长肌肉");}public void walk() {System.out.println("男人霸气的走路");}
}
public class Woman extends Person{boolean isBeauty;public void goShopping(){System.out.println("女人喜欢购物");}public void eat(){System.out.println("女人少吃,为了减肥。");}public void walk(){System.out.println("女人,窈窕的走路。");}
}
public class PersonTest{public static void main(String[] args){Person p1=new Person();p1.eat();Man man=new Man();man.eat();man.age=25;man.earnMoney();//**************************************//对象的多态性:父类的引用指向子类的对象Person p2=new Man();Person p3=new Woman();//多态的使用:当调用子父类同名同参数的方法时,实际执行的是子类重写父类的方法--虚拟方法调用p2.eat();p2.walk();//     p2.earnMoney();System.out.println(p2.id);//1001//不能调用子类所特有的方法,属性:编译时,p2是Person类型p2.name="Tom";//p2.isSmoking=true;//有了对象的多态性之后,内存中实际上是加载了子类特有的属性和方法的,但是由于变量声明为父类类型,导致编译时,只能调用父类中声明的属性或方法,子类特有的属性和方法不能调用//如果才能调用子类特有的属性或方法//向下转型:使用强制类型转换符Man m1=(Man)p2;m1.earnMoney();m1.isSmoking=true;//使用强转时,可能出现ClassCastExpection的异常//Woman w1=(Woman)p2;//w1.goShopping();}

 

 286 instanceof关键字的使用

 a instanceof A:判断对象a是否是类A的实例。如果是,返回true;如果不是,返回false

 实用情景:为了避免在向下转型时出现ClassCastExpection的异常,我们在向下转型之前,先进行intstanceof的判断,一旦返回true,就进行向下转型,如果返回false,不进行向下转型

如果a instanceof A返回true,则a instanceof B也返回true

其中,类B是类A的父类

if(p2 instanceof Woman){Woman w1=(Woman)p2;w1.goShopping();System.out.println("******Woman*********");
}
if(p2 instanceof Man){Man m2=(Man)p2;m2.earnMoney();System.out.println("*****Man************");
}
if(p2 instanceof Person){System.out.println("*****Person************");
}
if(p2 instanceof Object){System.out.println("*****Object************");
}

 287 向下转型的几个问题

练习

问题一:编译时通过,运行时不通过

//举例一

//Person p3=new Woman();

//Man m3=(Man) p3;

//举例二

Person p4=new Person();

Man m4=(Man)p4;

问题二:编译通过,运行时也通过

Object obj=new Woman();

Person p=(Person)obj;

//问题三:编译不通过    不相关的两个类不能运行

Man m5=new Woman();

String str=new Date();

Object o=new Date();

String str1=(String)o;

288 多态练习:调用方法和属性

public class FieldMethodTest {public static void main(String[] args){Sub s= new Sub();System.out.println(s.count);	//20s.display();//20Base b = s;//==:对于引用数据类型来讲,比较的是两个引用数据类型变量的地址值是否一样。System.out.println(b == s);	//trueSystem.out.println(b.count);	//10b.display();}
}class Base {int count= 10;public void display() {System.out.println(this.count);}
}class Sub extends Base {int count= 20;public void display() {System.out.println(this.count);}
}

练习:

1.若子类重写了父类方法,就意味着子类里定义的方法彻底覆盖了父类里的同名方法,
 * 系统将不可能把父类里的方法转移到子类中。编译看左边,运行看右边
 * 
 * 2.对于实例变量则不存在这样的现象,即使子类里定义了与父类完全相同的实例变量,
 * 这个实例变量依然不可能覆盖父类中定义的实例变量:编译运行都看右边

289 多态性练习:基本操作

建立InstanceTest 类,在类中定义方法method(Person e);
 * 
 * 在method中:
 * (1)根据e的类型调用相应类的getInfo()方法。
 * (2)根据e的类型执行:
 *         如果e为Person类的对象,输出:“a person”;
 *         如果e为Student类的对象,输出:“a student”“a person ”
 *         如果e为Graduate类的对象,输出:“a graduated student”
 *         “a student” “a person”

public class InstanceTest{public static void main(String[] args){Instance test=new InstanceTest();test.method(new Student());}public void method(Person e){//虚拟方法调用String info=e.getInfo();System.out.println(info);if(e instanceof Graduate){System.out.println("a graduated student");System.out.println("a student");System.out.println("a person");}else if(e instanceof Student){System.out.println("a student");System.out.println("a person");}else{System.out.println("a person");}}
}
class Person {protected String name = "person";protected int age = 50;public String getInfo() {return "Name: " + name + "\n" + "age: " + age;}
}class Student extends Person {protected String school = "pku";public String getInfo() {return "Name: " + name + "\nage: " + age + "\nschool: " + school;}
}class Graduate extends Student {public String major = "IT";public String getInfo() {return "Name: " + name + "\nage: " + age + "\nschool: " + school + "\nmajor:" + major;}
}

 


 

 

 

 

 

这篇关于尚硅谷Java入门哔哩哔哩274p-289p(2022.3.12)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/424095

相关文章

java使用protobuf-maven-plugin的插件编译proto文件详解

《java使用protobuf-maven-plugin的插件编译proto文件详解》:本文主要介绍java使用protobuf-maven-plugin的插件编译proto文件,具有很好的参考价... 目录protobuf文件作为数据传输和存储的协议主要介绍在Java使用maven编译proto文件的插件

Java中的数组与集合基本用法详解

《Java中的数组与集合基本用法详解》本文介绍了Java数组和集合框架的基础知识,数组部分涵盖了一维、二维及多维数组的声明、初始化、访问与遍历方法,以及Arrays类的常用操作,对Java数组与集合相... 目录一、Java数组基础1.1 数组结构概述1.2 一维数组1.2.1 声明与初始化1.2.2 访问

Javaee多线程之进程和线程之间的区别和联系(最新整理)

《Javaee多线程之进程和线程之间的区别和联系(最新整理)》进程是资源分配单位,线程是调度执行单位,共享资源更高效,创建线程五种方式:继承Thread、Runnable接口、匿名类、lambda,r... 目录进程和线程进程线程进程和线程的区别创建线程的五种写法继承Thread,重写run实现Runnab

Java 方法重载Overload常见误区及注意事项

《Java方法重载Overload常见误区及注意事项》Java方法重载允许同一类中同名方法通过参数类型、数量、顺序差异实现功能扩展,提升代码灵活性,核心条件为参数列表不同,不涉及返回类型、访问修饰符... 目录Java 方法重载(Overload)详解一、方法重载的核心条件二、构成方法重载的具体情况三、不构

Java通过驱动包(jar包)连接MySQL数据库的步骤总结及验证方式

《Java通过驱动包(jar包)连接MySQL数据库的步骤总结及验证方式》本文详细介绍如何使用Java通过JDBC连接MySQL数据库,包括下载驱动、配置Eclipse环境、检测数据库连接等关键步骤,... 目录一、下载驱动包二、放jar包三、检测数据库连接JavaJava 如何使用 JDBC 连接 mys

SpringBoot线程池配置使用示例详解

《SpringBoot线程池配置使用示例详解》SpringBoot集成@Async注解,支持线程池参数配置(核心数、队列容量、拒绝策略等)及生命周期管理,结合监控与任务装饰器,提升异步处理效率与系统... 目录一、核心特性二、添加依赖三、参数详解四、配置线程池五、应用实践代码说明拒绝策略(Rejected

一文详解SpringBoot中控制器的动态注册与卸载

《一文详解SpringBoot中控制器的动态注册与卸载》在项目开发中,通过动态注册和卸载控制器功能,可以根据业务场景和项目需要实现功能的动态增加、删除,提高系统的灵活性和可扩展性,下面我们就来看看Sp... 目录项目结构1. 创建 Spring Boot 启动类2. 创建一个测试控制器3. 创建动态控制器注

Java操作Word文档的全面指南

《Java操作Word文档的全面指南》在Java开发中,操作Word文档是常见的业务需求,广泛应用于合同生成、报表输出、通知发布、法律文书生成、病历模板填写等场景,本文将全面介绍Java操作Word文... 目录简介段落页头与页脚页码表格图片批注文本框目录图表简介Word编程最重要的类是org.apach

Spring Boot中WebSocket常用使用方法详解

《SpringBoot中WebSocket常用使用方法详解》本文从WebSocket的基础概念出发,详细介绍了SpringBoot集成WebSocket的步骤,并重点讲解了常用的使用方法,包括简单消... 目录一、WebSocket基础概念1.1 什么是WebSocket1.2 WebSocket与HTTP

SpringBoot+Docker+Graylog 如何让错误自动报警

《SpringBoot+Docker+Graylog如何让错误自动报警》SpringBoot默认使用SLF4J与Logback,支持多日志级别和配置方式,可输出到控制台、文件及远程服务器,集成ELK... 目录01 Spring Boot 默认日志框架解析02 Spring Boot 日志级别详解03 Sp