为什么Kotlin无法覆盖List< *>算子方法?

时间:2017-06-02 10:51:00

标签: kotlin

这是我的功能:

<?php
defined('BASEPATH') OR exit('No direct script access allowed');
class Test extends MY_Controller{
  function __construct() {
    parent::__construct();

    $this->load->helper('url');
    $this->load->model('Enquiry_model');
    $this->load->model('Quotation_model');
    $this->load->helper(array('form', 'url'));
    $this->load->library('form_validation');
    $this->load->library('session');
    $this->load->model('User');
    $this->load->model('Main_model');
    $this->load->model('Master_model');
    $this->is_logged_in();
  }
  public function index(){
    $data['user_data']=$this->is_logged_in();
    $this->load->view('admin1/quotation/test',$data);
  }
  public function test1(){
    $no_of_post=$this->input->post('no_of_post');
    //$no_of_post."<br>";

    $weight_box=0;
    $plate_box=0;
    $two_pipe_box=0;
    $four_pipe_box=0;

    if($no_of_post==1){
      $weight_box=1;
      $two_pipe_box=1;

      $total_box=floor($weight_box+$two_pipe_box);

    }else{
      $weight_box=round($no_of_post/2);
      $plate_box=ceil(($no_of_post/5));
      $four_pipe_box=$no_of_post/4;

      if (strpos($four_pipe_box,'.') !== false) {
        $four_pipe_box1=floor($four_pipe_box);
        $fraction=$four_pipe_box-$four_pipe_box1;
        if($fraction>=.60){
          $four_pipe_box=ceil($no_of_post/4);
          $total_box=floor($weight_box+$plate_box+$four_pipe_box);

        }else{
          $four_pipe_box=floor($no_of_post/4);
          $two_pipe_box=1;
          $total_box=floor($weight_box+$plate_box+$four_pipe_box+$two_pipe_box);
        }

      }else{
        $four_pipe_box=ceil($no_of_post/4);
        $total_box=floor($weight_box+$plate_box+$four_pipe_box);
      }
    }

    $arr= array($weight_box,$plate_box,$two_pipe_box,$four_pipe_box,$total_box);

    /*$arr[0]=$weight_box;
    $arr[1]=$plate_box;
    $arr[2]=$two_pipe_box;
    $arr[3]=$four_pipe_box;
    $arr[4]=$total_box;*/

    //$arr[0] = "Mark Reed";
    //$arr[1] = "34";
    //$arr[2] = "Australia";

    //echo json_encode($arr);
    echo json_encode(array_values($arr));
    //exit();
  }
}
?>

和我的用法:

operator  infix fun  List<Teacher>.get(int: Int): Teacher {
    var t = Teacher()
    t.name = "asd"
    return t ;
}

提示:b是一个具有List&lt;的对象。老师&gt;属性

和错误b[0].teachers[1].name

为什么这个覆盖操作符功能不起作用?

2 个答案:

答案 0 :(得分:8)

在Kotlin中,您不能使用扩展名遮蔽成员函数。呼叫解析中成员总是胜出。因此,您基本上不能调用具有与成员函数相同签名的扩展名,该扩展名存在于为表达式声明或推断的类型中。

class C {
    fun foo() { println("member") }
}

fun C.foo() { println("extension") }

C().foo() // prints "member"

在您的情况下,kotlin.collections.List中定义的成员函数为abstract operator fun get(index: Int): E

请参阅语言参考:Extensions are resolved statically

答案 1 :(得分:0)

正如voddan在评论中提到的那样,你不能为扩展方法蒙上阴影。但是,有一种方法可以通过一些多态来解决这个问题。我不认为我会建议你这样做,但我想这显示了一个很酷的Kotlin功能。

如果b[0]返回类型为B的对象,则可以在该类中执行此操作:

data class B(private val _teachers: List<Teacher> = emptyList()) {
    private class Teachers(private val list: List<Teacher>) : List<Teacher> by list {
        override operator fun get(int: Int): Teacher {
            var t = Teacher() 
            t.name = "asd"
            return t ;
        }
    }

    val teachers: List<Teacher> = Teachers(_teachers)
}

fun main(args: Array<String>) {
    println(B().teachers[0].name) // Prints "asd"
}

当我覆盖get - 函数时,它会影响使用B类的所有人,而不仅仅是导入扩展函数的位置。

请注意,我将Teachers - 类的所有其他方法调用委托给基础列表。