目录
目录
Java的数据类型
基本数据类型
引用数据类型
面向对象
封装
private关键字
继承
使用super调用父类中重写的方法、访问父类中被隐藏的字段
多态
组合
初始化快
抽象类:
接口:
集合
Collection
ArrayList
LinkedList
Map
泛型
常见修饰符学习:半成品
因为前面几天Java学的很烂,进了项目组后就不能再像之前那样没有目的的去学Java了;
首先了解一下Java的运行机制,Java是一种混合型的编译运行方式,它在执行代码时是首先把Java文件整体的编译为class文件 这个class文件也叫做字节码文件,然后再按行去交给设备去运行,在运行的时候也不是直接运行在系统中的,而是运行在虚拟机中(JVM),Java语言的跨平台实际上是通过虚拟机实现的;
JDK:Java的开发工具包,里面包含JVM虚拟机,核心类库,开发工具;
JRE:Java的运行环境;里面包含JVM,核心类库,运行工具;
JVM:Java虚拟机,真正运行Java程序的地方;
三者关系:JDK包含了JRE,JRE包含了JVM;
Java的数据类型分为两种,一种是基本数据类型,还有一种是引用数据类型 ;
基本数据类型有八个,分别是:type,short,int,long,char,float,double,boolean;
类、 接口类型、 数组类型、 枚举类型、 注解类型、 字符串型,例:String
类型就是引用类型。
理解面向对象,首先要了解类和对象;对象是面对对象方法中最基本的概念,是类的实例;类是具有共同属性,共同方法的一类事物。类是对象的抽象,对象是类的实例,并且类是整个软件系统最小的程序单元;
了解了类和对象,那我们要如何才能建立一个类呢;
Java语言里面定义类的简单语法如下:
[修饰符] class 类名
{
构造器定义;;
成员变量定义;
方法定义;
}
修饰符可以是public,final,abstract;类的修饰符到时候再具体讲;
在IDEA中;
一个类里面包三个最常见的成员:构造器,成员变量和方法,类之间成员的定义顺序没有任何影响,各成员之间可以相互调用,但是要注意的是,static修饰的成员不能访问没有static修饰的成员。
构造器:构造器是一个类创建对象的根本途径,如果一个类没有构造器,Java会为该类提供一个默认的构造器,但是如果你自己在类中写了构造器,那么默认的构造器也就没了;值得注意的是,在定义构造器时不能用void声明;倘若你使用了void来声明,那么Java就会把这个所谓的构造器当成方法来处理,还要注意,构造器名一定要和类名相同;
创建完类后,如何创建对象呢;
加载对象时,方法会被加载到栈内存中进行调用;
方法的重载
方法重载是指在一个类中定义多个同名的方法,但要求每个方法具有不同的参数的类型或参数的个数,方法重载的前提是方法的名字要相同;我找了一个比较详细的博客,放在下面了;方法的重载
方法的重载
封装是面向对象的三大特征之一,用白话理解,就是将东西放在一个箱子里面,只留下一个很小的口,只能通过特定的方法来使用里面的东西;
封装的原则:
将类的某些信息隐藏在类内部,不允许外部程序直接访问,而是通过该类提供的方法来实现对隐藏信息的操作和访问;例如成员变量private,提供对应的get()和set()方法;
封装的好处:
通过方法来控制成员变量的操作,提高了代码的安全性
把代码用方法进行封装,提高代码的复用性。
public class student {
private String name;
private int age;
private String xh;
public void setName(String name) {
this.name=name;
}
public String getName(){
return this.name;
}
public void setAge(int age){
this.age=age;
}
public int getAge(){
return this.age;
}
public void setXh(String xh) {
this.xh = xh;
}
public String getXh() {
return xh;
}
public student(){
}
public student(String name,int age,String xh){
this.name=name;
this.age=age;
this.xh=xh;
}
public void stady(String xk){
System.out.println(this.name+"正在学习"+xk);
}
}
这就是一个我写的类,里面的成员变量使用private修饰;
private:私有的;
作用:被private修饰的内容只能在本类中使用,其他类不能直接使用,但是其他类要是想访问这些内容,就要通过类所提供的访问方式,一般有两种访问方式;
1、设置器 setter : 为私有属性设置值
2、访问器 getter : 获取私有属性
成员变量和局部变量
成员变量是在类里面定义的变量,局部变量是在方法里面定义的变量;
成员变量又分为实例变量和类变量,用static修饰的就是类变量,不用static修饰的变量就是实例变量;
与成员变量不同的是,局部变量必须初始化之后才能访问它,不然就会出错;、
包
包(package) 是组织类的一种方式,使用包的主要目的是保证类的唯一性.例如:你在代码中写了一个 Test 类. 然后你的舍友也可能写一个 Test 类. 如果出现两个同名的类, 就会冲突, 导致代码不能编译通过。
Java已经帮我们提供了很多现成的类供我们使用,我们在调用他们的时候使用import语句来导入包;
使用 import static 可以导入包中的静态的方法和字段.
将类放到包中
基本规则:在文件的最上方加上一个 package 语句指定该代码在哪个包中
包名需要尽量指定成唯一的名字, 通常会用域名的颠倒形式(例如 com.bit.demo1 ).
包名要和代码路径相匹配. 例如创建 com.bit.demo1 的包, 那么会存在一个对应的路径 com/bit/demo1 来存储代码.
如果一个类没有 package 语句, 则该类被放到一个默认包中
详细请看包;
Java的常见包:
java.lang:系统常用基础类(String、Object),此包从JDK1.1后自动导入。
java.lang.reflect:java 反射编程包;
java.net:进行网络编程开发包。
java.sql:进行数据库开发的支持包。
java.util:是java提供的工具程序包。(集合类等) 非常重要
java.io:I/O编程开发包
这些包现在不用太过于了解,后面会随着学习的深入继续了解
继承是面向对象的三大特征之一,也是实现软件复用的重要手段,Java的继承有单继承的特点,每个子类只有一个直接父类;
Java的继承通过extends来实现,实现继承的类是子类,被继承的类是父类;比如水果和苹果的关系,苹果继承了水果,苹果是水果的子类,则苹果是一种特殊的水果;
父类的范围要比子类的大,可以认为父类是大类,子类是小类;
Java里面子类继承父类的语法格式如下:
修饰符 class Wife extends girlfriend_1{ //类定义部分; }在这里wife是你定义的子类的类名,girlfriend_1是父类的类名;
具有继承关系的子类和父类:子类具有父类的全部成员变量,方法和内部类(包括内部接口和枚举),值得提出的是,子类不能继承父类的构造器;
既然学了继承,那我们就要知道如何去重写父类的方法;
重写父类其实很简单,就是要注意“两同两小一大”规则,“两同”即方法名相同,形参列表相同;“俩小”指的是子类方法返回值类型应该比父类的要小或者相等;“一大”指的是子类方法的访问权限要比父类大或者相等;
这里,我在Wife类里面重写了wedding方法 ,原本的girlfriend类里面的wedding方法输出的是女朋友,但是经过重写后,变成了妻子;
当你想要调用父类中被重写的方法,就可以通过super关键字来实现,super和this一样都不能出现在static修饰的方法中;
先看下面代码:
package xuexi1;
public class girlfriend_1 {
public String girlfriend="李思敏";
public void base(){
System.out.println("父类的普通方法!");
}
public void text(){
System.out.println("父类被覆盖的方法!");
}
}
class Wife extends girlfriend_1{
//类定义部分;
public String girlfriend="王丹";
public void text(){
System.out.println("子类覆盖父类的方法!");
}
public void sub(){
System.out.println("子类的普通方法!");
}
public static void main(String[] args) {
girlfriend_1 a=new girlfriend_1();
System.out.println(a.girlfriend);
a.base();
a.text();
Wife b=new Wife();
System.out.println(b.girlfriend);
b.base();
b.text();
girlfriend_1 c=new Wife();
System.out.println(c.girlfriend);
c.base();
c.text();
//c.sub;
}
}
其中创建了三个引用变量a,b,c;其中a,b编译时类型和运行时类型完全相同,但是c编译时类型为girlfriend,但是他在引用时类型为Wife类型这就会出现多态了;下面是多态的一些特点;
编译看左边的意思是,Javac编译代码的时候,会看左边的父类有没有这个变量,如果没有,则编译失败;
多态的好处:使用父类作为参数,可以接受所以子类对象,体现多态的扩展性与遍历;
强制类型转换
1.基本类型的强转:只能在数值类型之间进行,这里所说的数值类型包括整形,字符型和布尔型;但是要注意的是,数值类型类型和布尔类型之间不能相互转换;
2.引用类型之间的转换只能在具有继承关系的两个类之间转换,如果试图将一个父类类型的实例转换成子类实例;
为了能够更好的了解类型转化,我看见一个讲的比较好的博客;
向上转型和向下转型
instanceof
用来判断一个对象是否是一个类或者其子类,实现类的实例,如果是则返回true,否则返回false;
使用格式:
对象名 + instanceof + 类名
多态的使用
前提:多态对象把自己看做是父类类型
组合和继承都是实现类复用的手段,他们两个个有个的优点和缺点;
组合和继承的联系
初始化块是Java类中的第四种成员(前面依次有成员变量和方法和构造器),一个类里面有多个初始化块,相同类型的初始化块之间有顺序,前面定义的初始化块先执行,后面定义的初始化块后执行;初始化块的语法格式为:
[修饰符] class {
//初始化块的可执行代码;
}
初始化块的修饰符自能是static,使用static修饰的的初始化块被称为类初始化块,没有static修饰的初始化块被称为实例初始化块;
包装类
原始类型: boolean,char,byte,short,int,long,float,double
包装类型:Boolean,Character,Byte,Short,Integer,Long,Float,Double
包装类创建的是对象,拥有方法和字段,对象的调用都是通过引用对象的地址,基本类型不是,还有就是包装类是引用传递,基本类型是值传递;
处理对象
1.打印对象和oStringt方法,当你创建一个对象然后直接用sout打印对象时;
可以看出,直接输出对象名实际上就是输出对象toString方法的返回值;
toString方法是Object类里面的一个实例方法,所有的Java类都是Object类的子类,因此所有的Java对象都有toString方法,它是一个”自我描述“的方法,该方法通常会用来实现一个功能:当程序员直接打印该对象时,系统将会输出该对象的自我描述信息,用来告诉外界该对象具有的状态信息;
2.==和equals方法
抽象方法和抽象类:
和类定义不同,接口不是使用class关键字,而是使用interface关键字,接口定义格式如下:
[修饰符] interface 接口名 extends 父接口1,父接口2......
{
零个到多个常量定义......
零个到多个抽象方法定义......
零个到多个内部类,接口,枚举定义......
零个到多个私有方法,默认方法或类方法定义......
}
接口中成员的特点 :
接口和类的区别:
JDK8以后接口中新增的方法:
作用:解决接口升级的问题
接口中默认方法的定义格式:
接口中默认方法的注意事项:
1.集合的概念:集合是Java中提供的一种容器,用来储存多个数据;
2.集合和数组的区别:
注意,用集合来存储数据的时候 存储不同类型的数据很不安全,于是我们可以使用泛型来实现集合中只能存储相同类型的数据;
集合基本分为两类:
1.Collection:单列集合,添加数据时,每次只能添加一个元素;
2.Map:双列集合,添加数据时,每次添加一对元素;
Collextion是单列集合的祖宗接口,它的功能是全部单列集合都可以继承使用的;
这是Collection中的一些方法;
小细节:contains方法的底层是通过equals方法来判断是否存在的;
所以如果集合中存储的是自定义对象,也想通过contains方法来判断是否包含,那么在Javabean类中,一定要重写equals方法;
Collection集合通用遍历方式
因为Collection集合有set儿子,而set系类集合是没有索引的,所以普通的for循环遍历实现不了;
Collection通用的遍历方式有:
迭代器遍历:
迭代器遍历最大的特点是不依赖索引;
细节注意点:
1,当你遍历完后再次使用next方法,系统会报错NoSuchElementException;
2,迭代器遍历完毕,指针并不会归位,如果还想要遍历,就要重新构造新的迭代器;
3,循环中只能使用一次next方法;
4,迭代器遍历时,不能用集合的方法进行增加或者删除,但是当你想要删除元素的时候,可以通过迭代器的删除方法删除;
增强for遍历;
增强for的底层就是迭代器Iterator,为了简化iterator的代码书写的;
使用对象:所有的单列集合和数组都能使用;
小细节:修改第三方变量的值不会影响集合中的元素;
Lambda表达式遍历;
当你遍历的时候想要删除元素的时候就选择迭代器遍历,啥也不干就选择增强for循环或Lambda表达式;
List系列集合:添加的元素是有序的,可重复,有索引;
List实现子类的特点:
- List集合类中元素有序(即添加顺序和取出顺序一致)、 且可重复
- List集合中的每个元素都有相对应的顺序索引,支持索引
- List中的元素都对应一个整数型的序号记载其在容器中的位置,可以根据其序号存取容器中对应的元素。
List集合在继承Collection集合的基础上可以通过索引来进行元素的增删查改;
小细节:根据remove来删除元素时,会优先选择根据索引来进行删除;
List集合遍历元素特有方法:ListIterator
该方法是Iterator的子接口;
改迭代器实现了在遍历的时候添加元素;
底层数据结构是链表,查询慢,增删快,但是如果操作的是首尾元素,速度也是极快的;
LinkedList本身多了很多直接操作首尾元素的特有API(接口);
Map常见API:
map集合常用API示例:
package Map;
import java.util.HashMap;
import java.util.Map;
public class A01 {
public static void main(String[] args) {
//1.创建集合:
Map m=new HashMap<>();
//2.添加元素;
m.put("宁舒意","李思敏");
m.put("刘洋","迪丽热巴");
m.put("李心力","彭航博");
//put方法的细节:
// 添加和覆盖;
//在添加数据的时候,如果键不存在,那么直接把键值对对象添加到map集合当中,方法返回null;
//在添加数据的时候,如果键是存在的,那么会把原有的键值对覆盖,会把覆盖的值进行返回;
// String s=m.put("刘洋","江疏影");
// System.out.println(s);
//删除;
//String result = m.remove("李心力");
//System.out.println(result);
//清空;
//m.clear();
//判断是否包含;
// boolean KeyResult=m.containsKey("宁舒意");
// System.out.println(KeyResult);
// boolean ValueResult = m.containsValue("李思敏");
// System.out.println(ValueResult);
//判段集合是否为空;
// boolean result =m.isEmpty();
// System.out.println(result);
int size =m.size();
System.out.println(size);
//3.打印集合
System.out.println(m);
}
}
Set系列集合:添加的元素是无序,不重复,无索引;
泛型的好处:
应用场景:
1.如果我们在定义类,方法,接口的时候,如果类型不确定,就可以定义泛型类,泛型方法,泛型接口;
2.如果类型不确定,但是能知道以后只能传递继承某个体系中的,就可以使用泛型的通 配符;
泛型的通配符:
关键点:可以限制类型的范围;