BaseActivity란 여러 Activity를 사용할 때 중복되는 코드를 미리 정의하여 소스를 간소화 및 간단하게 만든다.
화장품으로 치면 본격적인 화장에 들어가기 전에 바르는 파운데이션 느낌
abstract class BaseActivity<T: ViewDataBinding>
(@LayoutRes private val layoutId: Int): AppCompatActivity() {
protected lateinit var binding: T
override fun onCreate(savedInstanceState: Bundle?) {
beforeSetContentView()
// 필요에 따라 OnCreate, OnStart에
// Log를 붙여 생명주기를 관찰할 수도 있음
//Log.d(localClassName,"OnCreate")
super.onCreate(savedInstanceState)
binding = DataBindingUtil.setContentView(this, layoutId)
initView()
initViewModel()
initListener()
}
protected open fun beforeSetContentView() {}
protected open fun initView() {}
protected open fun initViewModel() {}
protected open fun initListener() {}
}
액티비티에서 사용하기
class MainActivity : BaseActivity<ActivityMainBinding>(R.layout.activity_main) {
override fun initView() {
super.initView()
// 바인딩을 해줄 필요가 없다. BaseActivity에서 이미 했기 때문
// binding = DataBindingUtil.setContentView(this, R.layout.activity_main)
...
}
// 필요에 따라 initViewModel() 등 다른 함수를 실행하기
// override fun initViewModel(){}
abstract class BaseFragment<T : ViewDataBinding>(
@LayoutRes val layoutId : Int
): Fragment() {
lateinit var binding : T
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
binding = DataBindingUtil.inflate(inflater, layoutId,container, false)
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
binding.lifecycleOwner = this
initView()
initViewModel()
initListener()
afterViewCreated()
}
protected open fun afterViewCreated(){}
protected open fun initListener(){}
protected open fun initViewModel(){}
protected open fun initView(){}
protected fun showToast(msg: String) =
Toast.makeText(context, msg, Toast.LENGTH_SHORT).show()
}
프로그래밍 언어에는 Int, Long, Char 등 여러 타입이 존재한다.
자신의 프로그램에 따라 타입을 적절하게 지정하는 것은 중요한데, 가끔은 모든 타입에 대해 동작을 하는 함수나 클래스를 구현하고자 할 때가 있다.
이 때 사용하게 되는 것이 제네릭
즉 제네릭(Generic)은 어떤 타입에 관계없이 일반화하는 것입니다.
fun main() {
println(add("1",2.1f)) //3.1
println(add("10","235")) //245.0
println(add(3,1)) // 4 class java.lang.Double
println(add("1.5",3.6)) //5.1
}
fun <T> add(a :T, b: T):T{
return (a.toString().toDouble() + b.toString().toDouble()) as T
}
타입에 관계 없이 String -> Double 순서로 강제 변환하여 연산이 가능하다.
더해서 String, Double을 넣을 수 있는 건 generic Type인 T를 매개변수로 놨기 때문
제네릭스를 사용하기 위해서는 타입 파라미터(type parameter)를 받는 타입을 정의하고, 인스턴스를 만들어 타입파라미터를 구체적인 타입 인자(type argument)로 치환해야한다.
Map<K, V> = > Map<String, Person>
더 자세히 파고들기엔 량이 너무 많아서 다음에 따로 더 공부하기로 하기
Generic과 Type Parameter