Kotlin 好多语法类似于 ES6 语法.
可以多看看ES6对前端或者其他开发语言都会有帮助.
fun main() {
var name: String ?= null
var aa = name !!.capitalize()
println(aa) // Exception in thread "main" java.lang.NullPointerException
}
var name: String ? = "james"
name = null
println(name?.capitalize()) // null
val num: Int? = "66.6".toIntOrNull()
println("num:$num") // null
fun main() {
// 匿名函数
showPersonInfo("James", 20, "男", "学习kotlin") {
println("1.显示个人信息: $it")
}
// 具名函数
showPersonInfo("MeiMei", 22, "女", "学习C++", ::showResultImpl)
}
fun showResultImpl(result: String) {
println("2.显示个人信息: $result")
}
inline fun showPersonInfo (name: String, age: Int, sex: String, study: String, showResult: (String) -> Unit) {
val str = "name: $name, age: $age, sex: $sex, study: $study"
showResult(str)
}
// 模拟登录
fun main() {
// lambda属于函数类型的对象,这里需要将responseResultFun普通函数改成函数类型的对象, 采用 ::
login("hujian1", "123456", ::responseResultFun)
}
fun responseResultFun(msg: String, code: Int) {
println("登录结果为,msg:${msg}, code:${code}")
}
const val USER_NAME_SAVE_DB = "hujian"
const val USER_PWD_SAVE_DB = "123456"
public inline fun login(name: String, pwd: String, responseResult: (String, Int) -> Unit) {
if(USER_NAME_SAVE_DB == name && USER_PWD_SAVE_DB == pwd) {
responseResult("登录成功!", 200) // 登录成功
} else {
responseResult("登录失败!", 500) // 登录失败
}
}
fun main() {
val anonymousFun = {
num1: Int, dou2: Double, str3: String ->
"参数1: ${num1}, 参数2: ${dou2}, 参数3: ${str3}"
}
println(anonymousFun(20, 11.22, "James"))
val anonymousFun2 = {
123.456
}
println(anonymousFun2())
val anonymousFun3 = {
num1: Int ->
num1 + 1
}
println(anonymousFun3(999))
}
fun main() {
val anonymousFun: (Int, Int, String) -> String = {
num1, num2, str3 ->
val inputValue = 123
"$inputValue Let`s go, 参数1: ${num1}, 参数2: ${num2}, 参数3: ${str3}, "
}
println(anonymousFun(18, 20, "James"))
}
fun main() {
val anonymousFun: () -> String = {
val inputValue = 123
"$inputValue Let`s go"
}
println(anonymousFun())
}
fun main() {
// 第一种情况下使用
`你好啊函数`("James", 18)
// 第二种情况使用: in,is 在Java中可当字符串使用,但是在kotlin中是关键字
TestClass.`is`()
TestClass.`in`()
}
private fun `你好啊函数` (name: String, age: Int) {
println("用户名:${name}, 年龄:${age}.")
}
fun main() {
show(102)
}
private fun show(number:Int){
when(number){
in 0..59 -> println("不及格")
in 60..100 -> println("及格")
else -> TODO("没有这种分数") // TODO不是提示语句,而是抛出Nothing异常,终止程序的代码
}
}
fun main() {
doWork()
}
private fun doWork() : Unit {
println("开始编码")
}
val garden = "黄石公园"
var time = 4
println("今天去${garden}玩了${time + time}个小时")
var isLogin = true
println("登录状态: ${if(isLogin)"登录成功" else "登录失败"}")
val week = 8
val info = when (week) {
1 -> "周一"
2 -> "周二"
3 -> "周三"
4 -> "周四"
5 -> "周五"
6 -> "周六"
7 -> "周日"
else -> {
println("其他")
}
}
println(info)
val number = 101
if (number in 0 .. 59) {
println("不及格")
} else if (number in 60 .. 100) {
println("及格")
} else {
println("分数不在0到100之间")
}
数据类型
Java中有两种数据类型: (1)基本类型:int double等. (2)引用类型: String 等.
Kotlin中只有一种数据类型,看起来都是引用类型,实际上编译器会在Java字节码中修改成"基本类型".
编译时常量
const val PI = 3.14
只能放在fun函数外
val 不可修改的变量
var name: String = “James”
val name: String = “James” // 根据Kotlin语言类型推断,需要简写成 val name = “James”
内置数据类型
String: 字符串
Char: 单字符
Boolean: true / false
Int: 整型
Double: 小数
List: 集合
Set: 无重复元素的集合
Map: 键值对的集合
kotlin介绍
(1)集聚各个语言的精华
(2)走向全栈语言
gravity 和 layout_gravity
android:gravity:是控件内部的对齐方式。可以理解为,本控件会影响到子控件的显示;
android:layout_gravity:组件对于父容器的位置。它的参照物是“父控件”;
录制视频 MediaRecorder , 视频播放 MediaPlayer, 音效播放 SoundPool
参考代码: C:\Users\HJ\Desktop\Android\Demo1\mediademo\src\main\java\com\example\mediademo
bundle传递数据, 通过实现Parcelable 和 Serializable 接口来传递对象
推荐方式: Android 中最好使用Parcelable,这个是安卓推荐,兼容安卓虚拟机,比Serializable性能高很多.
Room三角色
Student(Entity) StudentDao(DAO) StudentDatabase(DB)
记录: 模拟器中 Toast.makeText().show(); 不展示的问题
选择 AVD Manager, 执行一下 Wipe Data 操作,即可.
数据存储的选择
主要有: SP SQLite Room
(1) SP (sharedpreference 首选项)
存储软件的配置信息: window是用的ini, android用的XML.
应用场景:
自动登录,记住密码,主题记录等等.
首选项不能存储太多信息. 特点: 当程序运行首选项里面的数据会全部加载进内容.
很小,很简单的数据可以考虑存到首选项里去. 采用键值对的形式存储.
Java Object 、Array 、List 、Map 、Set 的序列化与反序列化
参考视频
List 、Map 、Set的反序列化需要获取下类型:
Type type = new TypeToken() { }.getType();
Type type = new TypeToken
OkHttp Cookie模拟代码
package com.example.hujian;
import androidx.annotation.NonNull;
import org.junit.Test;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import okhttp3.Call;
import okhttp3.Cookie;
import okhttp3.CookieJar;
import okhttp3.FormBody;
import okhttp3.HttpUrl;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
public class CookieUnitTest {
Map<String, List<Cookie>> cookies = new HashMap<>();
@Test
public void cookieTest() {
OkHttpClient okHttpClient = new OkHttpClient.Builder()
.cookieJar(new CookieJar() {
@Override
public void saveFromResponse(@NonNull HttpUrl httpUrl, @NonNull List<Cookie> list) {
cookies.put(httpUrl.host(), list);
}
@NonNull
@Override
public List<Cookie> loadForRequest(@NonNull HttpUrl httpUrl) {
List<Cookie> cookies = CookieUnitTest.this.cookies.get(httpUrl.host());
return cookies == null ? new ArrayList<>() : cookies;
}
})
.build();
FormBody formBody = new FormBody.Builder()
.add("username", "18066117765")
.add("password", "hujian761751953")
.build();
Request request = new Request.Builder().url("https://www.wanandroid.com/user/login")
.post(formBody).build();
//准备好请求的Call对象
Call call = okHttpClient.newCall(request);
try {
Response response = call.execute();
System.out.println("登录: " + response.body().string());
} catch (IOException e) {
e.printStackTrace();
}
request = new Request.Builder().url("https://www.wanandroid.com/lg/collect/list/0/json")
.build();
//准备好请求的Call对象
call = okHttpClient.newCall(request);
try {
Response response = call.execute();
System.out.println("获取收藏文章: " + response.body().string());
} catch (IOException e) {
e.printStackTrace();
}
}
}
// post 异步请求
public void postAsync(View view) {
FormBody formBody = new FormBody.Builder().add("a", "1").add("b", "2").build();
Request request = new Request.Builder().url("http://www.httpbin.org/post").post(formBody).build();
//准备好请求的Call对象
Call call = okHttpClient.newCall(request);
call.enqueue(new Callback() {
@Override
public void onFailure(@NonNull Call call, @NonNull IOException e) {
Log.d("James", "异步post请求失败");
}
@Override
public void onResponse(@NonNull Call call, @NonNull Response response) throws IOException {
if (response.isSuccessful()) {
Log.d("James", "异步post请求: " + response.body().string());
} else {
Log.d("James", "异步post请求异常");
}
}
});
}
@Test
public void uploadFileTest() throws IOException {
OkHttpClient okHttpClient = new OkHttpClient();
File file1 = new File("C:\\Users\\HJ\\Desktop\\test1.txt");
File file2 = new File("C:\\Users\\HJ\\Desktop\\test2.txt");
MultipartBody multipartBody = new MultipartBody.Builder()
.addFormDataPart("file1", file1.getName(), RequestBody.create(file1, MediaType.parse("text/plain")))
.addFormDataPart("file2", file2.getName(), RequestBody.create(file2, MediaType.parse("text/plain")))
.build();
Request request = new Request.Builder().url("http://www.httpbin.org/post").post(multipartBody).build();
Call call = okHttpClient.newCall(request);
Response response = call.execute();
System.out.println(response.body().string());
}
@Test
public void jsonTest() throws IOException {
OkHttpClient okHttpClient = new OkHttpClient();
RequestBody requestBody = RequestBody.create("{\"a\":\"1\", \"b\":\"2\"}", MediaType.parse("application/json"));
Request request = new Request.Builder().url("http://www.httpbin.org/post").post(requestBody).build();
Call call = okHttpClient.newCall(request);
Response response = call.execute();
System.out.println(response.body().string());
}
OkHttp 的同步与异步请求
参考视频
Glide 变换
ImageView iv_test = findViewById(R.id.iv_test);
Glide.with(this).load(R.drawable.image)
.transform(new RoundedCorners(50), new Rotate(90))
.into(iv_test);
热修复
在我们应用上线后出现bug需要及时修复时,不用再发新的安装包,只需要发布补丁包,在客户无感知下修复掉bug.
使用 Bugly: https://bugly.qq.com/docs/
Tinker是微信开源的一个热修复解决方案,支持dex、库和资源更新,无需重新安装apk.
开源地址: https://github.com/Tencent/tinker
@Nullable
@Nullable可以用在方法、属性、参数上。对应的意思分别如下:
方法:表示返回值可以是空
属性:表示属性值可以是空
参数:表示参数值可以是空
Android的四大组件
(1) Activity组件,它一个单独的窗口,程序流程都必须在【Activity】中运行,所有它是最基本的模块。
(2) service组件,用于在后台完成用户指定的操作。
(3) content provider组件,会为所有的应用准备一个内容窗口,并且保留数据库、文件。
(4) broadcast receiver组件,是程序之间传递信息时的一种机制,作用就是接收或者发送通知。分为系统广播和用户自定义广播.
记录: xml中代码背景为黄色的
<androidx.viewpager2.widget.ViewPager2
android:id="@+id/id_viewpager"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1">androidx.viewpager2.widget.ViewPager2>
将上面的代码改成单标签的形式
<androidx.viewpager2.widget.ViewPager2
android:id="@+id/id_viewpager"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" />
Activity 与 Fragment通信
(1) 原生方案: Bundle
(2) Java语言中类与类自己通信常用方案: 接口
(3) 其他方案: eventBus、LiveData
记录: android studio avd 一直处于 Waiting for all target devices to come online
试了各种方法都没用, 把这个AVD delete ,然后把 C:\Users\HJ.android\avd.android\avd 中相关文件删了,
重新下载了一个AVD,一切都正常了,
另外, Toast.makeText(FragmentManageActivity.this,“哈哈哈哈”,Toast.LENGTH_SHORT).show(); 不展示的问题也解决了.
记录: 新建一个module, xml文件中没有代码提示
将此module下的build.gradle文件中的 compileSdk 33 改成 30 即可.
Fragment 片段
(1) 具备生命周期,可以看作是子activity
(2) 必须委托在activity中才能运行.
dp 和 sp
(1) dip / dp : device independent pixels(设备独立像素),不同设备有不同的显示效果,这个和设备有关,一般我们为了支持WVGA、HVGA和QVGA推荐使用这个,不依赖像素px.
(2) sp: scaled pixels(放大像素),主要用于字体显示.
ListView
参考视频
RelativeLayout, TableLayout, GridLayout
参考视频
分割线
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="@color/purple_500"></View>
记录: Android Studio 中的AVD怎么都起不来,试了各种方法都没用.
最后把那个版本的AVD删了,然后把 C:\Users\HJ.android\avd 里的两个对应AVD文件删了,
重新下载了一个AVD就运行起来了.
Notification
参考视频
ImageView
当图片宽比较大,宽度到达300dp之后,图片就等比缩放到宽为300dp为止:
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:maxWidth="300dp"
android:maxHeight="300dp"
android:adjustViewBounds="true"
android:background="@color/xingrenhuang"
android:src="@drawable/background"></ImageView>
记录: Android Studio xml 文件中没有代码提示
在Gradle Scripts / build.gradle(Module:hujian.app)中,将compileSdk由33改为29
都不用重启Android Studio,代码提示就都出来了.
android 四大组件
(1) Activity 组件,它一个单独的窗口,程序流程都必须在【Activity】中运行,所有它是最基本的模块。
(2) service 组件,用于在后台完成用户指定的操作。
(3) content provider 组件,会为所有的应用准备一个内容窗口,并且保留数据库、文件。
(4) broadcast receiver 组件,是程序之间传递信息时的一种机制,作用就是接收或者发送通知。
参考文章
图像视图的缩放类型
(1) 代码中:
ImageView iv_scale = findViewById(R.id.iv_scale);
iv_scale.setImageResource(R.drawable.test);
iv_scale.setScaleType(ImageView.ScaleType.FIT_XY);
(2)XML文件中:
android:src=“@drawable/test”
android:scaleType=“fitXY”
图像视图 ImageView
图像视图展示的图片通畅位于 res / drawable *** 目录,设置图像视图的显示有两种方法:
(1)在XML文件中,通过属性android:src设置图片资源,属性值格式: “@drawable/不含扩展名的图片名称”
(2)在Java代码中,调用setImageResource方法设置图片资源,方法参数格式: “R.drawable.不含扩展名的图片名称”
bug 解决: android studio 中报 Lambda expressions are not supported at language level ‘7’
在lambda表达式中按 Alt + Enter, 点击 “Set language level to 8 - Lanbdas, type annotations etc.”
视图滚动
(1) ScrollView: 它是垂直方向的滚动视图; 垂直方向滚动时,layout_width属性值设置为match_parent, layout_height属性值设置为wrap_content.
(2) HorizontalScrollView: 它是水平方向的滚动视图; 水平方向滚动时,layout_width属性值设置为wrap_content, layout_height属性值设置为match_parent.
线性布局的权重 layout_weight
layout_width 填 0dp 时, layout_weight 表示水平方向的宽度比例.
layout_height 填 0dp 时, layout_weight 表示垂直方向的高度比例.
代码中设置视图的宽高
参考视频
计算规则
以一个 4.95 英寸 1920 * 1080 的 nexus5 手机设备为例:
Dpi:
计算直角边(即斜线长)像素数量: 1920^2 + 1080^2 = 2202^2 (勾股定理)
计算 Dpi: 2202 / 4.95 = 445
得到这个设备的Dpi为445 (每英寸的距离中有445个像素)
Density:
上面得到每英寸中有440像素,那么Density为每平方英寸中的像素数量,应该为: 445^2 = 198025
Dip:
所有显示到屏幕上的图像都是以px为单位,Dip是我们开发中使用的长度单位,最后它也需要转换为px,
计算这个设备上 1dip 等于多少px:
px = dip * dpi / 160
根据转换关系:
320 * 480 分辨率,3.6 英寸的手机: dpi为160, 所以在这个设备上: 1dp = 1px
结论:
对于相同分辨率的手机,屏幕越大,同 dp 的组件占用屏幕比例越小.
对于相同尺寸的手机,即使分辨率不同,同 dp 的组件占用屏幕比例也相同.
(1) 在Java代码中调用setTextSize方法, 默认单位sp.
(2) 在XML文件中通过android:textSize指定文本大小,此时需要指定字号单位(不指定会报错).
px: 它是手机屏幕的最小显示单位,与设备的显示屏有关.
dp: 它是与设备无关的显示单位,只与屏幕的尺寸有关. 也叫dip.
sp: 它专门用来设置字体大小,在系统设置中可以调整字体大小.
(3)尺寸解释
px: px是手机屏幕的最小显示单位,它与设备的显示屏有关. 一般来说,同样尺寸的屏幕(比如6英寸手机), 如果看起来越清晰,则表示像素密度越高,以px计量的分辨率也越大.
dp: dp 有时也写作dip,指的是与设备无关的显示单位,它只与屏幕的尺寸有关. 一般来说,同样尺寸的屏幕以dp计算的分辨率是相同的,比如同样是6英寸手机,无论它由哪个厂家生产,其分辨率换算成dp单位都是一样大小.
sp: sp的原理跟dp差不多,但它专门用来设置字体大小. 手机在系统设置里可以调整字体的大小. 设置普通字体时,同数值dp和sp的文字看起来一样大; 如果设置为大字体,用dp设置的文字没有变化,用sp设置的文字就变大了. 字体大小采用不同单位的话,显示的文字大小各不相同. 例如,30px、30dp、30sp这3个字号,在不同手机上显示大小有所差异. 有的手机像素密度较低,一个dp相当于两个px,此时30px等同于15dp; 有的手机像素密度较高,一个dp相当于3个px,此时30px等同于10dp. 假设某个 App 的内部文本使用字号30px, 该 App 安装到前一部手机的字体大小为15dp,安装到后一部手机的字体大小为10dp, 显然后一部手机显示的文本会更小.
Bug解决: “ERROR: Unable to start the daemon process. This problem might be caused by …”
(1) 修改项目中gradle.properties文件,只要添加以下一行代码: org.gradle.jvmargs=-Xmx512m
(2) 重启Android Studio
SharedPreference 共享参数用法
SharedPreference 是 Android 的一个轻量级存储工具, 采用的存储结构是Key-Value的键值对方式.
共享参数的存储介质是符合XML规范的配置文件. 保存路径是: /data/data/应用包名/shared_prefs/文件名.xml
利用元数据配置快捷菜单
(1)元数据的meta-data标签除了name属性和value属性,还拥有resource属性,该属性可指定一个XML文件,表示元数据想要的复杂信息保存于XML数据之中.
(2)利用元数据配置快捷菜单的步骤如下所示:
在res/values/strings.xml添加各个菜单项名称的字符串配置
创建res/xml/shortcuts.xml,在该文件中填入各组菜单项的快捷方式定义(每个菜单对应哪个活动页面)
给activity节点注册元数据的快捷菜单配置.
在代码里面设置启动标志
Intent.FLAG_ACTIVITY_NEW_TASK: 开辟一个新的任务栈
Intent.FLAG_ACTIVITY_SINGLE_TOP: 当栈顶为待跳转的活动实例时,则重用栈顶的实例
Intent.FLAG_ACTIVITY_CLEAR_TOP: 当栈中存在待跳转的活动实例时,则重新创建一个新实例,并清除原实例上方的所有实例
Intent.FLAG_ACTIVITY_NO_HISTORY: 栈中不保存新启动的活动实例
Intent.FLAG_ACTIVITY_CLEAR_TASK: 跳转到新页面时,栈中的原有实例都被清空
Android生命周期详解
onCreate: 创建活动. 把页面布局加载进内存,进入了初始状态.
onStart: 开始活动. 把活动页面显示在屏幕上,进入了就绪状态.
onResume: 恢复活动. 活动页面进入活跃状态,能够与用户正常交互,例如允许响应用户的点击动作、允许用户输入文字等等.
onPause: 暂停活动. 页面进入暂停状态,无法与用户正常交互.
onStop: 停止活动. 页面将不在屏幕上显示.
onDestroy: 销毁活动. 回收活动占用的系统资源,把页面从内存中清除.
onRestart: 重启活动. 重新加载内存中的页面数据.
onNewIntent: 重用已有的活动实例.
参考文章
Activity的启动和结束
从当前页面跳到新页面:
startActivity(new Intent(源页面.this, 目标页面.class));
从当前页面回到上一个页面,相当于关闭当前页面,返回代码如下:
finish(); // 结束当前的活动页面
按钮控件有两种常用的监听器
点击监听器,通过setOnClickListener方法设置. 按钮被按住少于500毫秒时,会触发点击事件.
长按监听器,通过setOnLongClickListener方法设置. 按钮被按住超过500毫秒时,会触发长按事件.
视图对齐方式
设置视图对齐方式有两种途径:
layout_gravity: 它指定当前视图相对于上级视图的对齐方式
gravity: 它指定下级视图相对于当前视图的对齐方式
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="400dp"
android:background="#ffff99"
android:orientation="horizontal">
<LinearLayout
android:layout_width="0dp"
android:layout_height="200dp"
android:layout_gravity="bottom"
android:layout_margin="10dp"
android:layout_weight="1"
android:background="#ff0000"
android:gravity="left"
android:padding="10dp">
<View
android:layout_width="100dp"
android:layout_height="100dp"
android:background="#00ffff"></View>
</LinearLayout>
<LinearLayout
android:layout_width="0dp"
android:layout_height="200dp"
android:layout_margin="10dp"
android:layout_weight="1"
android:background="#ff0000"
android:gravity="right|bottom"
android:padding="10dp">
<View
android:layout_width="100dp"
android:layout_height="100dp"
android:background="#00ffff"></View>
</LinearLayout>
</LinearLayout>
视图的宽高
视图宽度 android:layout_width , 视图高度 android:layout_height
宽高的取值主要有以下三种:
(1)match_parent: 表示与上级视图保持一致
(2)match_content: 表示与内容自适应
(3)以dp为单位的具体尺寸
完整的页面创建过程包括三个步骤:
(1)在layout目录下创建XML文件
(2)创建与XML文件对应的Java代码
(3)在AndroidManifest.xml中注册页面配置
Activity
Activity是一个应用程序组件,提供一个屏幕,用户可以用来交互为了完成某项任务.
Gradle
Gradle是一个项目自动化构建工具,帮我们做了依赖、打包、部署、发布、各种渠道的差异管理等工作.
App工程目录结构
App工程分为两个层次,第一个层次是项目,另一个是模块.
模块依附于项目,每个项目至少有一个模块,也能拥有多个模块.
一般说的"编译运行App"值得是运行某个模块,而非运行某个项目,因为模块才对应实际的App.
Android采用Log工具打印日志,它将各类日志划分为五个等级
Log.d: 表示调试信息,可把程序运行时的变量值打印出来,方便跟踪调试. (用的最多)
Log.e: 表示错误信息,比如可能导致程序崩溃的异常.
Log.w: 表示警告信息.
Log.i: 表示一般信息.
Log.v: 表示冗余信息.
SDK
Software Development Kit 软件开发工具包,它可将App源码编译为可执行的App应用
Android Studio 中的快捷键
Ctrl + Alt + L 代码格式化
Ctrl + Shift + Enter键 快速开启下一行进行编辑
Alt + Enter 引入包
Ctrl + O 快捷生成内部类
Ctrl + / 单行注释
Ctrl + Shift + / 多行注释
连按两下shift键进行搜索查询
Ctrl + Alt + F 点回车,快速私有化全局变量
Ctrl + Shift + R 批量替换
参考视频
参考介绍链接
1.什么是Jetpack
Jetpack 是一个由多个库组成的套件,可帮助开发者遵循最佳做法,减少样板代码,并编写
可在各种Android版本和设备中一致运行的代码,让开发者精力集中编写重要的代码.
一、抽象类和抽象方法
● 抽象类: 抽象类中可以没有抽象方法, 抽象类不能实例化对象.
public abstruct class Pet {
// 每个子类的实现不同
public void shout () {}
}
● 抽象方法: 抽象方法不能实现,因为不是具体的方法,直接以分号结束,不能有{}方法体,没有实现.
- 抽象方法所在的类必须是抽象类.
- 抽象类要求继承它的子类必须实现抽象方法,如果没有实现,要求该子类也必须加abstruct修饰.
- public abstruct viod shout(); // 没有实现体
二、多态的引入
开闭原则: 对扩展开放,对修改关闭.
多态: 针对子类的不同实现对象,针对同一个方法,表现不一样.
同一个引用类型,使用不同的实例,而执行不同操作.即父类引用指向不同子类对象.
三、重写
● 子类要重写的方法必须和父类或接口里面的方法名完全一样.
● 子类要重写的方法必须和父类或接口里面的参数的类型,个数,顺序完全相同.
● 子类要重写的方法返回值类型至少要比父类或者接口更加严格.
四、方法重载和方法重写
五、static
public class MyMath {
// number被static修饰之后,就可以通过 MyMath.number 直接获取了.
// 没有用static修饰的话,就需要new MyMath()创建一个实例化才能访问.
public static int number = 10;
}
static修饰的方法:
示例:
int[] arr = {1,3,2,5,4};
Arrays.sort(arr);
静态代码块,只执行一次,优于方法之前执行. 比如数据库连接,io下载:
六、final
◆ 用final修饰的类不能被继承,例如 String 这个类使用final修饰的,所以String是不能被继承的.
◆ 用final修饰的方法不能被重写.
◆ 在Java里面使用 static final 修饰的变量称为 常量,不能被修改,必须有初始值. 尽量都写成大写的.
七、接口
特点:
▪ 接口是完全抽象的.
▪ 接口是一套规范.
▪ 接口里面定义的字段属性全是常量, 默认加 public static final 修饰.
▪ 接口定义的方法全是抽象方法, 默认都有 public abstruct 修饰.
▪ 接口可以充分解耦合,所以有面向接口编程.
▪ 一个子类可以实现多个接口,却只能继承一个父类.
▪ 接口可以继承接口,接口不能继承类.
八、如何实现多态
满足多态三要素:
▪ 继承父类或者实现接口
▪ 子类重写父类或接口里面的抽象方法
▪ 父类或接口引用指向子类实例化的对象
(1) 继承中访问修饰符
(2) 不能被继承的父类资源: private成员,构造方法.
(类中加了有参数的构造方法后,无参构造方法也是必须保留的,这样才是一个完整的类)
(3) super
super表示父类的对象,super()只能在子类构造方法里面才能出现,而且必须放在第一行.
super() 表示调用父类无参构造方法
super(name) 表示调用父类带一个name的构造方法.
(4) 执行顺序,后面执行的可能会覆盖前面的值
子类构造方法 => 父类构造方法 => 父类属性赋初始值 => 子类属性赋初始值
(5) 如果一个类没有显示继承,都默认继承Object类.
(6) Java里面是单继承,只能继承一个父类.
(1) 封装
面向对象语言中,我们操作的是一个又一个对象。这些对象的数据与操作数据的方法会被封装到特定的类里面,我们在使用的时候不需要关心该对象的某些方法是如何实现的,只需要调用类提供的接口即可使用这些方法。这就是封装的含义。
(2) 继承
当一个类是另一个类的特例时,我们可以让这个特例的类去继承另一个类,这样,这个特例的类被称作子类,而继承的类被称作父类。这样子类不仅能有父类的特性,还可以有自己的额外扩展,这就是继承的含义。
(3) 多态
多态的含义可以表达为“对外提供一个接口,内部可以有多种实现”。
Java中的类和对象
参考链接
类:
(1) 创建类后没有手动添加构造方法时,系统默认有一个没有参数的构造方法.
(2) 当给类手动添加构造方法后,默认无参的构造方法将不存在,需要我们手动添加一个无参的构造方法.
堆栈相关知识
参考视频
Java 八种基本数据类型
又可以分成四个大类:
(1) 整型: byte, short, int, long
(2) 浮点型: float, double
(3) 字符型: char
(4) 布尔型: boolean
(PS: 引用数据类型主要有: 数组(类型),类(类型),接口(类型),包装类型.)
JavaBean的概念
JavaBean 是一个公共的(public)类
JavaBean 有一个不带参数的构造方法
JavaBean 通过setXXX方法设置属性,通过getXXX方法获取属性
典型JavaBean 实例:
public class CounterBean{
private int count = 0;
public CounterBean(){ }
public int getCount(){
return count;
}
public void setCount(int count){
this.count = count;
}
}
自动装箱: 指开发人员可以把一个基本数据类型直接赋给对应的包装类.
自动拆箱: 指开发人员可以把一个包装类对象直接赋给对应的基本数据类型.
典型应用:
List list = new List();
list.add(1); //加的是整型的对象
int j = (Integer) list.get(0);
Integer i = 1; //装箱
int j = i; //拆箱
GUI: 图形化界面(Graphical User Interface)
CLI: 命令行方式(Command Line Interface)
JRE(Java Runtime Enviroment): Java运行环境
JDK(Java Development Kit): Java 开发工具包
IDE (Integrated Development Environment): 集成开发环境
API (Application Programming Interface): 应用程序编程接口
OOP(Object Oriented Programming): 面向对象程序设计
AOP(Aspect Oriented Programming): 面向切面编程