JAVA学习Day10【面对对象4】
学习视频:https://www.bilibili.com/video/BV17J411G72L?p=20178-195
/*
*类的成员:
*(1)属性,成员变量
*(2)方法,成员方法
*(3)构造器
*(4)代码块:非静态代码块,静态代码块
*
*
*/
/*
*非静态代码块中的代码在什么时候执行?
*每次在创建对象的时候都执行,且比构造器早
*
*实例初始化过程,创建对象时,为对象进行初始化的操作:
*(1)为成员变量显示赋值
*(2)执行非静态代码块
*(3)执行构造器
*Java编译器其实会把这三个部分的代码合成一个叫做<init>(【形参列表】)实力初始化方法
*即编译后的class字节码信息中,是没有构造器这个概念
*<init>(【形参列表】)实力初始化方法的代码就是由三个部分组成
*(1)成员变量显示赋值的代码
*(2)非静态代码块中的代码
*(3)执行构造器中的代码
*(1)(2)按顺序执行,(3)一定是它们当中的最后执行
*
*而且,有几个构造器,就会有几个实例初始化的方法,那么导尿管你创建对象的时候,调用对应的构造器时,其实执行的是对应的实例初始化方法<init>(【...】)
*
*/
public class Test10_01{
public static void main(String[] args){
MyClass my1 = new MyClass();//调用无参构造
MyClass my2 = new MyClass("atguigu");//调用有参构造
Demo d1 = new Demo();
Demo d2 = new Demo("atguigu");
}
}
class MyClass{
private String str = "hello";//显示赋值
public MyClass(){
System.out.println("无参构造");
}
public MyClass(String str){
this.str = str;
System.out.println("有参构造");
}
{
System.out.println("非静态代码块");
}
}
class Demo{
private String str = assign();
public Demo(){
System.out.println("无参构造");
}
public Demo(String str){
this.str = str;
System.out.println("有参构造");
}
{
System.out.println("非静态代码块");
}
public assign(){
System.out.println("assign方法");
return "hello";
}
}
/*
*实例初始化示例(1)看一下运行结果并解释!!!!!!!!!!!!
*
*/
public class Test10_02{
public static void main(String[] args){
//Father f = new Father();
//Son s = new Son();
//Son s2 = new Son("atguigu");
Son s3 = new Son("atguigu", 10);
}
}
class Father{
public Father(){
System.out.println("父类的无参构造");
}
}
class Son extends Father{
private String str;
public Son(){
//隐含了super();子类构造器中一定会调用父类的构造器,默认调用父类的无参构造
System.out.println("子类的无参构造");
}
public Son(String str){
//隐含了super();子类构造器中一定会调用父类的构造器,默认调用父类的
this(str);
this.num = num;
System.out.println("子类中的有参构造");
}
}
/*(1)先执行父类的实例初始化方法
*它由三部分组成
*1.成员变量的显式赋值 2.非静态代码块 3.构造器
*(2)再执行子类的实例初始化方法
*1.成员变量的显式赋值 2.非静态代码块 3.构造器
*
*super()或super(实参列表)之前说的是调用父类的构造器,其实是调用父类对应的实例初始化方法
*super()或super(实参列表)之前说的是在子类构造器的首行,其实是在子类实例初始化方法的首行
*
*/
public class Test10_03{
public static void main(String[] args){
Zi z = new Zi();
}
}
class Fu{
private String str = assign();
{
System.out.println("(1)父类的非静态代码块");
}
public Fu(){
System.out.println("(2)父类的无参构造")
}
public String assign(){
System.out.println("(3)父类的assign()");
return "fu";
}
}
class Zi extends Fu{
private String strZi = assignZi();
{
System.out.println("(4)子类的非静态代码块");
}
public Zi(){
//super(); ==> 调用父类的实例初始化方法,而且它在子类实例初始化方法的首行
System.out.println("(5)子类的无参构造");
}
public String assignZi(){
System.out.println("(6)子类的assignZi()");
return "zi";
}
}
/*
*面向对象的基本特征:1.封装 2.继承 3.多态
*多态:多种形态
*变量的引用形式:
*(1)本态引用:左边的变量与右边的对象是同一种类型
*(2)多态引用,左边的变量是父类类型,右边的对象是子类的对象
*
*多态的表现特征:编译类型与运行时的类型不一致
*编译的时候,按照父类类型编译的
*执行的方法是子类重写的方法
*编译看左边,运行看右边
*
*多态的前提:(1)继承(2)重写(3)多态引用
*
*用途:方法的动态绑定
*多态和属性无关,只和方法有关
*/
public class Test10_04{
public static void main(String[] args){
//1.本态引用
Person p = new Person();
Woman w = new Woman();
Man m = new Man();
//2.多态引用
Person p2 = new Woman();
Person p3 = new Man();
p2.eat();
p2.walk();
p2.shop();//不能调用
}
}
class Person{
public void eat(){
System.out.println("吃饭");
}
public void walk(){
System.out.println("走路");
}
}
class Woman extends Person{
public void eat(){
System.out.println("细嚼慢咽");
}
public void walk(){
System.out.println("婀娜");
}
public void shop(){
System.out.println("买买买");
}
}
class Man extends Person{
public void eat(){
System.out.println("狼吞虎咽");
}
public void walk(){
System.out.println("大摇大摆");
}
public void smoke(){
System.out.println("吐烟");
}
}
/*
*多态的应用
*(1)多态数组
*
*/
public class test10_05{
public static void main(String[] args){
//创建一个数组,可以存储各种图的对象,包括圆、矩形等等
Graphic[] all = new Graphic;
all = new Circle(1.3);
all = new Rectangle(2,4);
for(int i = 0; i < all.length; i++){
System.out.println("面积:" + all.getArea());
}
}
}
class Graphic{
public double getArea(){
return 0.0;
}
}
class Circle extends Graphic{
private double radius;
public Circle(double radius){
this.radius = radius;
}
public double getArea(){
return 3.14 * radius * radius;
}
}
class Rectangle extends Graphic{
private double length;
private double width;
public Rectangle(double length, double width){
this.length = length;
this.width = width;
}
//重写
public double getArea(){
return length * width;
}
}
/*
*多态的应用
*(2)多态参数
*
*/
public class test10_06{
//检查所有动物吃东西是否正常
public static void check(Animal a){
a.eat();
}
public static void main(String[] args){
//匿名对象
check(new Dog());
check(new Cat());
Dog d = new Dog();
check(d);
}
}
class Animal{
public void eat(){
System.out.println("吃东西");
}
}
class Dog extends Animal{
public void eat(){
System.out.println("啃骨头");
}
}
class Cat extends Animal{
public void eat(){
System.out.println("吃鱼");
}
}
/*
*类型转换:向上转型与向下转型
*1.基本数据类型的转换
(1)自动类型转换
*byte -> short -> int -> long -> float -> double
* char ->
*(2)强制类型转换
*double -> float -> long -> int -> short -> byte
*->char
*2.引用数据类型数据
*父子类之间的转换(不是父子类之间是不能进行向上与向下转型的)
*(1)向上转型 从子类到父类
*(2)向下转型 从父类到子类
*为什么要向上转型?
*因为多态数组、多态参数的应用场景,使得有时候不得不向上转型,这样是为了方便统一管理各种子类对象
*为什么要向下转型?为了调用子类特有的方法
*是否所有的父类向下转型都会成功呢?
*要想转型成功,之前必须要向上转型,才能向下转型
*
*
*异常总结:
*(1)ArrayIndexOutOfBoundsException:数组下标越界异常
*(2)NullPointerException:空指针异常
*对象.属性
*对象.方法
*如果对象是null,就会发生空指针异常
*(3)ClassCastException:类型转换异常
*向下转型时,可能会发生
*
*/
public class Test10_07{
public static void main(String[] args){
//(1)向上转型
Person p = new Woman();//多态引用
//一旦把Woman对象向上转型为Person后,就只能调用父类的方法
p.eat();
p.walk();
//(2)向下转型
//在这里调用Woman特有的方法
Woman m = (Woman)p;
m.shop();
Person p2 = new Person();
Woman w2 = (Woman) p2;//类型转换错误
w2.shop();
Person p3 = new Man();
Woman w3 = (Woman) p3;//类型转换错误
w3.shop();
}
}
class Person{
public void eat(){
System.out.println("吃饭");
}
public void walk(){
System.out.println("走路");
}
}
class Woman extends Person{
public void eat(){
System.out.println("细嚼慢咽");
}
public void walk(){
System.out.println("婀娜");
}
public void shop(){
System.out.println("买买买");
}
}
class Man extends Person{
public void eat(){
System.out.println("狼吞虎咽");
}
public void walk(){
System.out.println("大摇大摆");
}
public void smoke(){
System.out.println("吐烟");
}
}
/*
*向下转型时会有风险,可能会发生ClassCastException
*因为这是个运行异常,不能提前发现
*使用代码避免,用instanceof
*
*什么情况下用instanceof判断返回true?
*if(p instanceof Woman) 当p中存储的就是Woman的对象
*if(p instanceof Woman) 当p中存储的是Woman的子类对象
*/
public class Test10_08{
public static void main(String[] args){
}
public static void test(Person p){
//如果这个p是个女人,就调用它的shop方法
//如果这个p是个男人,就调用它的smoke方法
//如果这样写会出问题,因为Person包含了Woman和Man
/*
*if(p instanceof Person){
* p.eat();
* p.walk();
*}else*/if(p instanceof Woman){
Woman m = (Woman) p;
m.shop();
}else if(p instanceof Man){
Man m = (Man) p;
m.smoke();
}
}
}
还是通俗易懂得
页:
[1]