糖逗 发表于 2020-8-19 19:35:05

JAVA学习Day10【面对对象4】

学习视频:https://www.bilibili.com/video/BV17J411G72L?p=20

178-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();
                }
               
        }
}

阿法国 发表于 2020-8-22 19:38:08

hassoun 发表于 2020-9-2 09:58:12

还是通俗易懂得
页: [1]
查看完整版本: JAVA学习Day10【面对对象4】