关于继承的一些疑问。

关于继承的一些疑问。

  1. 子类不能继承父类原型里面的方法吗?

  2. 在子类的非静态方法中调用super获取的只能是父类的原型吗?

  3. 在子类静态方法中调用super只能获取父类的静态属性吗?在构造函数内设置的属性,我试了无法获取。

  4. 继承函数后不是有一个操作叫做方法重写吗?在js中方法全部自己跑到原型中去了(无法被继承),是不是就没有重写这个操作了?只能算是给子类定义了一个新方法(与父类名字相同)?

我自己的测试代码:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title></title>
</head>
<body>
    <script type="text/javascript">
        class Human{
            constructor(){
                this.say="哈哈哈";
                this.age=88;
            };
            

            say(){
                console.log("我是方法");
            };
        }
        Human.total=99999999;

        class Man extends Human{
            constructor(){
                super();
            }

            manSay(){
                console.log(super.age);
                super.say();
            }
            static manSayTwo(){
                console.log(super.age);
                console.log(super.total);
            }
        }

        console.log(new Human());
        let bob=new Man();
        bob.manSay();
        Man.manSayTwo();
        console.log(bob.age);
    </script>
</body>
</html>


正在回答

登陆购买课程后可参与讨论,去登陆

4回答

你好同学,参考如下理解:

<!DOCTYPE html>

<html>


<head>

    <meta charset="utf-8">

    <title></title>

</head>


<body>

    <script type="text/javascript">

        class Human {

            constructor() {

                // this指向实例化对象,这里的属性是实例化对象的属性。

                // 这里的属性与下面原型上的方法重名了,老师上一次把方法名给你改过一次,

                // 这里你可以改一下属性名,实例化的时候调用bob.say()就能成功了。

                this.say = "哈哈哈";

                this.age = 88;

            };


           // 非静态方法,是放在Human原型上的方法 (注意与上面的属性同名了)

            say() {

                console.log("我是方法");

            };

            // 静态方法,能被子类继承,但是不能被实例化对象继承。

            static pp() {

                console.log("我是静态方法");

            };

        }


        // 它相当于静态属性

        Human.total = 99999999;



        class Man extends Human {

            constructor() {

                super();

            }


            manSay() {


                // -----------------------------------------------------------------------------------

                // age是实例化对象的属性,只能通过this访问。

                // super.age没有办法访问到

                // console.log(super.age); 

                // -------------------------------------------------------------------------------------

                //非静态方法中,super指向的是父类原型对象,即prototype

                // total相当于Human的静态方法,所以这里访问不到。

                // console.log(super.total);

                // -------------------------------------------------------------------------------------

                // say是Human原型对象上的方法,可以访问到

                // super.say();

            }

            static manSayTwo() {

                // -----------------------------------------------------------------------------------

                // 静态方法中,super指向的是父类。 只能访问父类静态方法和静态属性。

                // ---------------------------------------------------------------------------------

                // age不是静态属性,所以访问不到。

                // console.log(super.age); 

                // ----------------------------------------------------------------------------------

                // total属性静态属性,所以可以访问

                // console.log(super.total); 

            }

        }



        let bob = new Man();

        //你在Human中定义的属性和方法重名了。在实例化的过程中

        // 先把父类的prototype对象放在实例的__proto__上,即say方法放在了实例bob的原型上

        // 然后才会执行父类的构造函数,因为实例化的时候,类里面的this指向的是实例化对象

        // 所以say属性和age属性都成了实例bob自身上的属性。

        // 当你调用bob.say()的时候,会先调用bob自身的属性(如果没有才会在bob原型上找)

        // bob本身有say这个属性,并且值为“哈哈哈” ,使用函数的调用方式就会报错“bob.say不是一个函数”

        // bob.say();



        bob.manSay();


        Man.manSayTwo();


        console.log(bob.age);


        // class Foo{

        //     static classMethods(){

        //         console.log('成功');

        //     }

        // }


        // 之前老师想要说的是不能被子类的实例继承,但是没有表达清楚。给同学带来了疑惑很抱歉。静态方法可以被子类继承,只是不能被实例化对象继承。

 

        // class Bar extends Foo{};

 

        // Bar.classMethods();



   

    </script>

</body>


</html>

祝学习愉快,望采纳。

  • ssszz 提问者 #1
    谢谢老师,讲的很详细了!
    2019-09-07 10:51:05
提问者 ssszz 2019-09-06 15:11:58

我重新将疑问注释在代码上了,麻烦老师在帮我看一下= ̄ω ̄=。

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title></title>
</head>
<body>
    <script type="text/javascript">
        (function(){
            class Human{
                constructor(){
                    this.say="哈哈哈";
                    this.age=88;
                };
                

                say(){
                    console.log("我是方法");
                };
            }
            Human.total=99999999;

            class Man extends Human{
                constructor(){
                    super();
                }

                manSay(){
                    // console.log(super.age);
                    console.log(super.total);//这两个super我有点没弄懂,他们分别指向什么额
                    // super.say();
                }
                static manSayTwo(){
                    console.log(super.age);//这两个super我有点没弄懂,他们分别指向什么额
                    console.log(super.total);//为什么静态函数中的super才能调用total
                }
            }

            console.log(new Human());

            let bob=new Man();

            // bob.say();//为什么这里会报错,bob不应该有say()方法吗?
            
            bob.manSay();

            Man.manSayTwo();

            console.log(bob.age);
        })()


        // class Foo{
        //     static classMethods(){
        //         console.log('成功');
        //     }
        // }

        // class Bar extends Foo{};

        // Bar.classMethods();//输出成功,静态方法也能被继承吗?
    </script>
</body>
</html>


提问者 ssszz 2019-09-05 20:49:34

关于2、3,老师之前我看其他问答这个有一点没弄懂了,

http://img1.sycdn.imooc.com//climg/5d70ff04000102b907490623.jpg

我以为静态函数中的super就能够访问其父类构造函数中的属性,可以我测试的子类中manSay()方法用super就访问不到父类的total的值,而在其静态函数中super就能后访问其父类的total,我有点乱。

我想问一下这两个super的区别。

还有一个这个,老师关于静态函数,下面代码算是继承了吗?

        class Foo{
            static classMethods(){
                console.log('成功');
            }
        }

        class Bar extends Foo{};

        Bar.classMethods();

http://img1.sycdn.imooc.com//climg/5d71041f0001193509710256.jpg

  • 提问者 ssszz #1
    还有4中,老师如果Man成功继承了Human的方法的话,那么我用bob.say()应该也能够在控制台输出”我是方法“吧,可是我一调用bob.say()就报错,说我没定义它 Uncaught TypeError: bob.say is not a function
    2019-09-06 09:34:00
好帮手慕夭夭 2019-09-05 20:08:18

你好同学,解答如下:

1.子类可以继承父类原型的上面的方法哦,因为super指向的就是父类的原型,所以在子类中,使用super可以调用到父类原型上面的方法,而不能调用父类本身上面的属性。

参考如下理解:

http://img1.sycdn.imooc.com//climg/5d70f7490001873112040665.jpg

2. 子类super指向的是父类的原型,所以只能调用到原型上的。与是不是子类非静态方法无关。

3.子类使用super就可以调用到父类原型上的属性,与是不是子类的静态方法也无关。而父类的静态属性,是不能被继承的,所以父类上的静态方法无法被子类访问。

构造函数中设置的属性是父类自身的方法,类里面的this指向的是实例化对象,当实例化的时候,这些属性都会被实例对象继承,所以需要使用this访问。

http://img1.sycdn.imooc.com//climg/5d70f83c000197b203870092.jpg

4.最后一个问题不是很明白同学的意思,老师先按照理解的意思给你讲一下,如果没有解答疑惑,可以重新描述清楚哦。

像如下方法就是父类原型上的,这个方法是会继承的

http://img1.sycdn.imooc.com//climg/5d70f9860001ed4207160260.jpg

假如说子类也有一个同名的方法

http://img1.sycdn.imooc.com//climg/5d70f9b700013c0105060217.jpg

那么在实例化子类的时候,子类的整个方法会把父类上的覆盖掉而已。所以实例去调用它,输出的就是22

http://img1.sycdn.imooc.com//climg/5d70fa2b0001f56c02430059.jpg

但是如果你在子类中,使用super调用,super是指向父类原型的,所以它还是会输出"我是方法"

http://img1.sycdn.imooc.com//climg/5d70fa7f0001520a03210053.jpg

祝学习愉快,望采纳。


问题已解决,确定采纳
还有疑问,暂不采纳

恭喜解决一个难题,获得1积分~

来为老师/同学的回答评分吧

0 星
请稍等 ...
意见反馈 帮助中心 APP下载
官方微信

在线咨询

领取优惠

免费试听

领取大纲

扫描二维码,添加
你的专属老师