一、继承的概念和基本语法
定义:在原有类的基础上定义一个新类,原有类称为父类,新类称为子类。
class 子类名 extends 父类名 { 类体 }
语法:假设定义Parents为父类,C1为子类,通过关键字extends子类便可以继承父类的特性,相关代码为:
class C1(参数可选) extends Parents(参数可选){ }
二、继承的好处
一旦我们完成了继承,就可以直接在子类的对象中调用父类的方法。
继承的特点:Dog就直接具备了animal的功能eating。
/*
1.多个类
2.继承
class 子类 extends 父类
3.好处:不劳而获。子类可以直接使用父类的属性和方法
*/
object class10 {
// 动物
class Animal(var name:String="动物") {
val age:Int=10
def eat(): Unit={
println("animal eat")
}
def run():Unit={
println("amimal run")
}
}
// 狗
class Dog() extends Animal(){
}
def main(args: Array[String]): Unit = {
val d1=new Dog()
d1.eat()
d1.run()
}
}
三、继承的方法重写
格式:
override def 方法名(参数可选) { }
/*
1.多个类
2.继承
class 子类 extends 父类
3.好处:不劳而获。子类可以直接使用父类的属性和方法
4.子类对父类的方法的重写
在子类中,通过override 覆盖(重写)父类的同名方法
5.super. 在子类中访问父亲
*/
object class11 {
class Parent() {
val name:String=""
def run():Unit={
println("run")
}
}
class son() extends Parent(){
// 如果希望对父类的方法进行改进:觉得不好
def run1():Unit={
}
override def run():Unit={
super.run() // super.run 在子类中,调用父亲的方法
println("开自动驾驶的车 run")
}
}
def main(args: Array[String]): Unit = {
val s1=new son()
s1.run()
}
}
四、继承与多态
面向对象的三个特点:封装,继承_ ,__ 多态 __ 。同一操作作用于不同的对象, 可以有不同的解释,产生不同的执行结果,这就是多态性。
/*
1.多个类
2.继承
class 子类 extends 父类
3.好处:不劳而获。子类可以直接使用父类的属性和方法
4.子类对父类的方法的重写
在子类中,通过override 覆盖(重写)父类的同名方法
5.super. 在子类中访问父亲
6.面向对象编程的三大特征:封装,__继承____,__多态__
*/
object class12 {
class Fruit() {
def eat():Unit={
println("eat")
}
}
class Apple extends Fruit{
override def eat():Unit={
println("吃掉果皮,中间的不能吃")
}
}
class Watermelon extends Fruit{
override def eat():Unit={
println("削皮,中间的最好吃")
}
}
def main(args: Array[String]): Unit = {
// 参数类型:父亲
def test(fruit: Fruit):Unit={
fruit.eat()
}
val a1=new Apple()
test(a1) // 传入子类
val w1=new Watermelon()
test(w1)
}
}
五、构造器的调用顺序
代码验证调用顺序:父类的构造器->子类构造器
7.构造器的调用顺序:先调用父类的,再调用子类的
*/
object class13 {
class Father() {
println("Father的构造器")
}
class son extends Father(){
println("son的构造器")
}
def main(args: Array[String]): Unit = {
// 创建一个子类对象时,
// 先调用父类的构造器→子类的构造器
new son()
}
}
六、带参构造器的写法
1. 父类构造器正常写。
2. 在写子类构造器时:
(1)如果某个属性可以从父类中继承过来,那么这些属性就不要添加任何的修饰符(val,var都不加)如果这属性是子类自己特有的,就需要补充修饰符;
(2)在父类构造器时,直接传入对应的参数。
8.当父类,子类都存在带参数的构造器时,如何进行参数传递
*/
object class14 {
// 父类
class Animal(var name:String,var age:Int) {
println(s"父类的构造器被调用....${name},${age}")
def say():Unit={
println(s"Animal ${name},${age}")
}
}
// 子类
class Dog(name:String,age:Int,var color:String) extends Animal(name, age){
println(s"子类的构造器被调用....${name},${age},${color}")
override def say():Unit={
super.say()
println(s"狗狗....,我的颜色是${color}")
}
}
def main(args: Array[String]): Unit = {
val d1=new Dog("旺财",1,"黑色")
d1.say()
}
}