python中子类对父类初始化变量的赋值

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了python中子类对父类初始化变量的赋值相关的知识,希望对你有一定的参考价值。

比如,我有两个类,B继承A类,都声明了构造函数
class A: def __init__(self,aa,ab): class B(A): def __init__(self,??):那么,我在A类中改怎么添加参数呢?是先写父类的初始化参数还是不写?
还有,在B类的构造函数中,是直接调用A类构造函数,或者Supre(B,self)函数来初始化呢,还是要下面这样来初始化,比如
self.x = x
self.y =y
这样的方式?
谢谢大家了,看了些资料,翻了些书,要么说的模模糊糊,要么一笔带过

1、使用self.x = x这样来添加变量
2、对于父类的初始化参数,如果不写,默认就使用父类无参的__init__方法
3、子类初始化父类参数B.__init__(self,aa,ab)
4、使用super(子类类型,子类对象).foo()调用父类方法
参考技术A 1、使用self.x = x这样来添加变量
2、对于父类的初始化参数,如果不写,默认就使用父类无参的__init__方法
3、子类初始化父类参数B.__init__(self,aa,ab)
4、使用super(子类类型,子类对象).foo()调用父类方法
参考技术B '''
desc:当子类重写了__init__方法,仍然需要调用父类的构造方法,就需要super(子类,self).__init__(参数),子类初始化父类的属性
'''

class Father(object):
def __init__(self, wife):
self.name = '父类属性'
self.wife = wife

class Son(Father):
def __init__(self,wif):
Father.__init__(self,wife=wif)
self.address = "湖北"

som = Son('dwdw')
print(som.wife)
参考技术C 代码:
class A:
def __init__(self,aa,bb):
print('class A',aa,bb)
class B(A):
def __init__(self,aa,bb):
super().__init__(aa,bb)
print('class B',aa,bb)

b=B(11,22)
super(B,b).__init__(3,4)

结果:
class A 11 22
class B 11 22
class A 3 4

知道了吧?如果不清楚,最好就是自己写个简单的demo测试下

第五次JAVA课,java语法基础课件总结

思索

  技术分享图片

  构造函数是对类的成员变量进行初始化,子类拥有父类的可继承的成员变量,若要用到父类的成员变量,就必须对其初始化,所以在子类构造函数运行前要调用父类构造函数对父类成员变量初始化。

  绝对不能反过来。因为特性是优先子类的特性,若调用玩父类构造函数后在调用子类构造函数,会有可能导致子类特性被覆盖,从而产生错误。

 

“类型转换”

class Mammal{}
class Dog extends Mammal {}
class Cat extends Mammal{}

public class TestCast
{
    public static void main(String args[])
    {
        Mammal m;
        Dog d=new Dog();
        Cat c=new Cat();
        m=d;
        //d=m;
        d=(Dog)m;
        //d=c;
        //c=(Cat)m;
    }
}

   在使用继承的过程中,不可避免的会遇到需要通过子类来调用父类方法的情况,所以为了解决父类子类拥有相同方法导致前者方法无法被调用的情况,java就必须拥有多态的特性——可以让一个父类变量引用一个子类对象,而编译器会由引用的对象类型来判断如何编译。但这没解决如何使一个子类对象调用父类方法,所以可以用强制类型转换类解决,把一个子类的类型暂时当做父类来处理。

  可以使用instanceof运算符判断一个对象是否可以转换为指定的类型。

 

在实践中理解把握复杂的知识

public class ParentChildTest {
    public static void main(String[] args) {
        Parent parent=new Parent();
        parent.printValue();
        Child child=new Child();
        child.printValue();
        
        parent=child;
        parent.printValue();
        
        parent.myValue++;
        parent.printValue();
        
        ((Child)parent).myValue++;
        parent.printValue();
    }
}
class Parent{
    public int myValue=100;
    public void printValue() {
        System.out.println("Parent.printValue(),myValue="+myValue);
    }
}
class Child extends Parent{
    public int myValue=200;
    public void printValue() {
        System.out.println("Child.printValue(),myValue="+myValue);
    }
}

  上面代码运行结果为:

Parent.printValue(),myValue=100
Child.printValue(),myValue=200
Child.printValue(),myValue=200
Child.printValue(),myValue=200
Child.printValue(),myValue=201

  前面两个可以理解,后面就不太一样了。第三个是父类的引用装子类的对象拿前朝的剑斩本朝的官,本朝的当然不会让你斩啊,但编译器还是调用子类方法。第四个有点难,如果调试时查看父类的myValue,可以看到这个myValue是101(加了1),但由于方法调用的是子类的方法所以输出仍然为200且隐形参数为Child,成员变量使用父类变量,方法调用却是子类方法,很奇怪,所以第五个是用强制转换的方式,这样变量也是子类的变量了。关于这种奇怪的现象会在“多态”里总结。

 

“多态”

  不想多说,直接总结:

一、使用父类类型的引用指向子类的对象; 
二、该引用只能调用父类中定义的方法和变量; 
三、如果子类中重写了父类中的一个方法,那么在调用这个方法的时候,将会调用子类中的这个方法;(动态连接、动态调用) 
四、变量不能被重写(覆盖),”重写“的概念只针对方法,如果在子类中”重写“了父类中的变量,那么在编译时会报错。

  这样多态是通过父类和继承父类并覆盖父类中同一方法的几个不同子类、接口和实现接口并覆盖接口中同一方法的几不同的类体现的。通过超类对象引用变量引用子类对象但对消息的反应是子类的方式来实现多态。

 

  java为了实现多态性采用了后绑定(动态绑定)的形式。

程序绑定的概念:
绑定指的是一个方法的调用与方法所在的类(方法主体)关联起来。对java来说,绑定分为静态绑定和动态绑定;或者叫做前期绑定和后期绑定

静态绑定:
在程序执行前方法已经被绑定,此时由编译器或其它连接程序实现。例如:C。
针对java简单的可以理解为程序编译期的绑定;这里特别说明一点,java当中的方法只有final,static,private和构造方法是前期绑定

动态绑定:
后期绑定:在运行时根据具体对象的类型进行绑定。
若一种语言实现了后期绑定,同时必须提供一些机制,可在运行期间判断对象的类型,并分别调用适当的方法。也就是说,编译器此时依然不知道对象的类型,但方法调用机制能自己去调查,找到正确的方法主体。不同的语言对后期绑定的实现方法是有所区别的。但我们至少可以这样认为:它们都要在对象中安插某些特殊类型的信息。

动态绑定的过程:
虚拟机提取对象的实际类型的方法表;
虚拟机搜索方法签名;
调用方法。

——https://www.xuebuyuan.com/2965081.html

  在java中,几乎所有的方法都是后期绑定的,在运行时动态绑定方法属于子类还是基类。但是也有特殊,针对static方法和final方法由于不能被继承,因此在编译时就可以确定他们的值,他们是属于前期绑定的。特别说明的一点是,private声明的方法和成员变量不能被子类继承,所有的private方法都被隐式的指定为final的(由此我们也可以知道:将方法声明为final类型的一是为了防止方法被覆盖,二是为了有效的关闭java中的动态绑定)。java中的后期绑定是有JVM来实现的,我们不用去显式的声明它,而C++则不同,必须明确的声明某个方法具备后期绑定。

以上是关于python中子类对父类初始化变量的赋值的主要内容,如果未能解决你的问题,请参考以下文章

Java中this和super关键字

java如何在子类中赋值给父类的变量

第五次JAVA课,java语法基础课件总结

Java对象实例化顺序

父类的成员变量赋了值,子类继承该变量,值还是父类的值吗?

Java的private成员变量的继承问题