面向对象
面向对象是一种思想;
面向对象就是将功能封装进对象,强调具备了功能的对象
面向对象三个特征:封装、继承、多态
类
类是一个模板,它描述一类对象的行动和状态。
一个源文件中只能由一个public类,且public类的类名必须和源文件同名。一个源文件可以有多个非public类
类名由若干个单词组成,每个单词的首字母都应该大写。(大驼峰法)
类有外部类、抽象类、final类、内部类、匿名类等
外部类不可声明为private
一个类不能同时被abstract和final修饰。
被final修饰的类不能被继承
对象
一、对象是类的实例,有状态和行为
二、Java中使用new关键字来创建一个新对象,对象在堆内存中。
三、Puppy myPuppy = new Puppy(“tommy”) //myPuppy 是类类型变量
四、通过创建的对象可以访问类中的变量和方法。
五、对象初始化过程
Puppy myPuppy = new Puppy(“tommy”)
new对象的时候,jvm 会将类文件加载到内存并加载静态变量和静态方法,
执行静态代码块,
在堆内存中开辟空间,分配内存地址
在堆内存中建立对象的特有属性并默认初始化,
对对象显示初始化,
执行构造代码块初始化对象,
执行构造函数初始化对象
将堆内存队长赋给栈内存中的变量
六、对象调用成员过程
匿名对象
一、匿名对象就是没有名字
二、匿名对象的两种使用情况(1)当对对象方法仅调用一次时;(2)匿名对象可以作为实际参数进行传递
new A().pro=5;
局部变量
在方法、构造方法或者语句块中定义的变量称为局部变量。变量声明和初始化都在方法中,方法结束后,变量会自动销毁。
访问修饰符不能修饰局部变量
局部变量是在栈上分配的
局部变量没有默认值,被声明后必须初始化才可以使用。
示例:
package com.runoob.test;
public class Test{
public void pupAge(){
int age = 0;
age = age + 7;
System.out.println("小狗的年龄是: " + age);
}
}
实例变量(成员变量)
成员变量是定义在类中,方法体之外的变量。这种变量在创建对象的时候实例化。成员变量可以被类中方法、构造方法和特定类的语句块访问。
每个对象都有独特的实例变量,对象的状态由这些实例变量的值决定。
实例变量在对象创建时被创建,在对象被销毁时销毁。
访问修饰符可以修饰实例变量
实例变量的值可以在声明时指定,也可以在构造方法中指定。
成员变量在堆内存中
import java.io.*;
public class HelloWord {
public String name;
private double salary;
public HelloWord(String empName){
name = empName;
}
public void setSalary(double empSal){
salary = empSal;
}
public static void main(String[] args) {
System.out.println("Hello World!");
}
}
类变量
定义在类中,方法体之外,但必须声明为static类型。
类变量也称静态变量。
静态变量被存储在静态存储区。常用来申明常量。
静态变量在第一次被访问时创建,在程序结束时销毁。
静态变量可通过classname.variablename 的方式访问。
无论一个类实例化多少对象,它的静态变量只有一份拷贝。
封装
隐藏对象的属性和实现细节,仅对外提供公共访问方式
封装的原则:(1)将不需要向外提供的内容隐藏起来(2)把属性都隐藏,提供公共方法对其访问
执行顺序:静态代码块>构造代码块>构造函数>普通代码块
静态代码块
在java类中使用static关键字和{}声明的代码块,方法中不能存在静态代码块
一、格式:
static{
静态代码块中的执行语句
}
class StaticCode{
static{
system.out.println("ss");
}
}
静态代码块在类被加载的时候就运行了,而且只运行一次,并且优先于各种代码块以及构造函数。
构造代码块
在java类中使用{}声明的代码块(和静态代码块的区别是少了static关键字):
作用:给对象进行初始化
对象一建立就运行,优先于构造函数运行
构造代码块是给所有对象进行初始化;
public class CodeBlock {
{
System.out.println("构造代码块");
}
public CodeBlock(){
System.out.println("无参构造函数");
}
public CodeBlock(String str){
System.out.println("有参构造函数");
}
}
构造函数
每个类都有构造方法。
如果没有显式定义构造方法,java编译器会为该类提供一个默认的构造方法
自定义构造函数后,系统不会提供默认的构造函数
在创建对象时,至少要调用一个构造方法。
构造方法的名称必须和类同名,
构造方法没有返回值,不可以写return,也不用定义返回值类型
一个类可以有多个构造方法
构造函数可以私有化,私有化后不可创建对象
public class Puppy{
public Puppy(){ //自定义构造函数
}
public Puppy(String name) {
}
}
构造函数可以用于给对象统一进行初始化;构造函数是给对应对象进行初始化
默认构造函数的权限和所属类一致。
普通代码块
普通代码块和构造代码块类似,但是构造代码块是在类中定义的,而普通代码块是在方法体中定义的。
普通代码块的执行顺序和书写顺序一致。
class Test{
public void sayHello(){
{
System.out.println("普通代码块");
}
}
}
类、以及类中变量和方法的加载顺序
父类静态变量,父类静态代码块,
子类静态变量,子类静态代码块,
父类非静态变量,父类构造代码块,父类构造函数,
子类非静态变量,子类构造代码块,子类构造函数。
this关键字
一、this代表当前对象
二、当定义类中函数时,该函数内部要用到调用该函数的对象时,用this来表示这个对象
三、this关键字在构造函数中的使用,构造函数间调用只能用this函数,并且this语句只能定义在构造函数的第一行
class Demo(){
String name;
int age;
Demo(String name){
this.name=name;
}
Demo(String name, int age){
this(name);
this.age=age;
}
static关键字
用于修饰变量和静态方法
被修饰的变量和方法随着类的加载而加载;优先于对象存在;被所有对象共享;可以直接被类名调用,类名.静态成员;
静态方法只能访问静态成员和静态方法;静态方法中不可使用this和super;
主函数是静态的,主函数只能调用静态函数
类只要存在,静态成员就存在;类消失了,静态成员就消失了
工具类:使用静态定义函数,并将构造函数私有化,强制不让该类创建对象
制作帮助文档
Public 修改的类才可设置帮助文档
单例设计模式
一、一个类只能创建一个对象就是单例模式
继承与重写
一、提高代码的复用性;是多态的前提;
class Person(){
string name;
int age;
}
class Student extends Person(){
}
二、子类继承父类中非私有变量;父类中变量和子类中变量一样时,子类变量会覆盖父类变量;子类中使用父类中的变量使用super.num
三、子类方法继承父类非私有方法;子类和父类的方法相同时,子类覆盖了父类的方法;子类中使用父类中的方法使用super.;子类覆盖父类,必须保证子类权限大于等于父类权限;静态方法只能覆盖静态方法;
四、覆盖就是重写,重写要求子类和父类方法要一模一样
五、子类不能继承父类的构造方法;创建子类对象时会先执行父类的构造函数,因为子类的构造函数默认第一行有一条隐式的super();子类构造函数调用父类构造函数使用super()函数;父类没有空参数的构造函数时,子类需显式指定调用父类的哪个构造函数
六、super()必须写在构造函数的第一行;构造函数里要么有super()语句,要么有this()函数,两个不能同时存在
final关键字
一、可修饰类、变量和函数
二、被final修饰的类不可被继承
三、被final修饰的方法不可复写
四、被final修饰的变量是常量只能赋值一次,可以修饰成员变量和局部变量
五、static常与final一起使用,共享数据
六、内部类定义在类中的局部位置时,只能访问该局部被final修饰的局部变量
抽象
一、当多个类中出现相同功能,但是功能主题不同,可以向上抽取,只抽取功能定义,而不抽取功能主体
二、抽象方法必须存放在抽象类中,抽象类不可创建对象
abstract class Student{
abstract void study();
}
三、使用抽象类中的方法必须由其子类复写所有的抽象方法;如果子类只覆盖了部分抽象方法,该子类仍然是抽象类
四、抽象类中即可以有抽象方法也可以有非抽象方法。
五、抽象类中可以不定义抽象方法,作用是不让该类创建对象
Arrays 类
Arrays类可以方便的操作数组,它提供的所有方法都是静态方法。
给数组赋值:通过 fill 方法。
对数组排序:通过 sort 方法,按升序。
比较数组:通过 equals 方法比较数组中元素值是否相等。
查找数组元素:通过 binarySearch 方法能对排序好的数组进行二分查找法操作
字符串
1、在java中字符串属于对象。
2、java提供了String类来创建和操作字符串。
3、使用关键字或者构造器创建字符串。
public class HelloWord {
public static void main(String[] args) {
// 使用关键字创建字符串
String greeting = "菜鸟";
// 使用构造方法创建字符串
String Reet = new String("菜鸟1");
}
}
4、获取字符串长度
String site = "www.runoob.com";
int len = site.length();
5、连接字符串,常使用+,也可以使用concat()方法。
String a = "菜鸟b";
String b = "菜鸟c";
System.out.println(a +"+"+b);
System.out.println(a.concat(b));
6、字符串格式化
public class HelloWord {
public static void main(String[] args) {
float floatVar = 2f;
int intVar = 2;
String fs = String.format("浮点型变量的值为"+"%f,整型变量的值为" +
"%d", floatVar, intVar);
System.out.println(fs);
}
}
7、字符串常用方法
public class HelloWord {
public static void main(String[] args) {
String s = "asdfa";
String s2 = "adf";
// 返回指定索引处的char值
System.out.println(s.charAt(2));
// 返回指定字符或者字符串在字符串中第一次出现的索引
System.out.println(s.indexOf("f"));
// 返回指定字符或者字符串在字符串中最后一次出现的索引
System.out.println(s.lastIndexOf("f"));
//按ascii码顺序比较,先比较第一个字符,依次类推,返回值是整数。
System.out.println(s.compareTo(s2));
// 将指定字符串连接到此字符串的结尾
System.out.println(s.concat(s2));
System.out.println(s.startsWith("f"));
System.out.println(s.endsWith("f"));
System.out.println(s.equals(s2));
System.out.println(s.equalsIgnoreCase(s2));
// 使用指定的字符集将String编码为byte序列,并将结果存储在一个新的byte数组中
byte [] b = s.getBytes();
System.out.println(b.length);
char[] c = s.toCharArray();
System.out.println(c);
// 返回字符串的哈希值
System.out.println(s.hashCode());
// 返回字符串长度
System.out.println(s.length());
// 将字符串中的所有oldchar替换为newchar
System.out.println(s.replace("a","b"));
// 根据给定的正则表达式的匹配拆分此字符串,可指定拆分次数
System.out.println(s.split("f").length);
// 返回子序列
System.out.println(s.substring(1,2));
System.out.println(s.toUpperCase());
// 返回字符串的副本,忽视前导空白和尾部空白
System.out.println(s.trim());
}
}
StringBuffer 和 StringBuilder 类
使用StringBuffer和StringBuilder类可以对字符串进行修改,且不会产生新的未使用对象。
StringBuilder非线程安全,但是比StringBuffer有速度优势。
StringBuffer是线程安全的,在应用程序有线程安全的情况下必须使用StringBuffer类。
public class HelloWord {
public static void sysOut(String args){
System.out.println(args);
}
public static void main(String[] args) {
StringBuffer sBuffer = new StringBuffer("菜鸟教程官网");
sBuffer.append("www");
sBuffer.append(".runoob");
sBuffer.append(".com");
// 反转字符串
sBuffer.reverse();
sBuffer.reverse();
// 移除字符
sBuffer.delete(1,3);
// 在指定位置插入字符串
sBuffer.insert(1,"sds");
// 将指定位置的字符串替换为指定字符
sBuffer.replace(1,3,"");
sysOut(sBuffer.toString());
}
}
访问控制修饰符
修饰符 | 说明 |
---|---|
default | 默认修饰符,不使用任何关键字。在同一个包内及同一包内的子孙类可见 |
public | 对所有类可见 |
protected | 对同一包内的类和所有子类可见 |
private | 在同一个类内可见 |
非访问控制修饰符
final、abstract、static、synchronized
包装类
在实际开发中我们经常需要使用对象,而不是内置数据类型。为此java语言为内置数据类型提供了包装类。
Number类
java为每种基本数据类型都提供了对应的包装类(Integer、Long、Byte、Double、Float、Short)。所有的包装类都是抽象类Number 的子类。
这种由编译器特别支持的包装称为装箱。
当内置数据类型被当作对象使用的时候,编译器会把内置类型装箱为包装类。相似的,编译器也可以把一个对象拆箱为内置类型。
Number 类属于 java.lang 包。
public class HelloWord {
public static void main(String[] args) {
Integer x = 5;
x = x+10;
System.out.println(x);
}
}
Character 类
1、Character类用于对单个字符进行操作;
2、Character类在对象中包装一个基本类型char的值。
public class HelloWord {
public static void main(String[] args) {
//创建Character类对象
Character ch = new Character('c');
// 是否是一个字母
System.out.println(Character.isLetter('c'));
// 返回指定字母的大写形式
System.out.println(Character.toUpperCase('c'));
// 判断是否是一个数字字符
System.out.println(Character.isDigit('c'));
// 返回字符串形式,字符串的长度为1
System.out.println(Character.toString('c'));
}
}
接口
¥接口只定义派生要用到的方法,但是方法的具体实现完全取决于派生类。
¥java8前接口里不可以实现方法,java8后可以实现方法
¥java8以后可以在接口中定义默认方法和静态方法,且默认方法优先于抽象方法
¥在接口添加了一个默认方法,所有的实现类就自动继承,不需要改动任何实现类,也不会影响业务。另外,接口默认方法可以被接口实现类重写。
¥接口静态方法和默认方法类似,只是接口静态方法不可以被接口实现类重写。
¥接口静态方法只可以直接通过静态方法所在的 接口名.静态方法名 来调用。
¥接口中的方法默认是public
¥接口中的变量默认是 public static final
¥接口默认方法多继承冲突问题
接口A实现了a方法->接口B实现了a方法->实现类C实现了A 和B ====>JVM不知道C类要继承哪个a方法
解决方法:类C重写a方法
class C extends B implement A {
@Override
default void eat() {
People.super.eat();
Man.super.eat();
System.out.println("男孩吃饭");
}
}
抽象类
抽象类不能被用来实例化对象。
如果一个类中包含了抽象方法,那么该类一定是抽象类
抽象类可以包含抽象方法和非抽象方法
抽象类中也可以不包含抽象方法
任何继承抽象类的子类必须实现父类的所有抽象方法,否则还是抽象类。
修饰符对类的影响
项目 | 外部类 | 内部类 | 接口 | 抽象类 | 匿名类 |
---|---|---|---|---|---|
public | Y | Y | Y | Y | |
default | Y | Y | Y | Y | |
protected | N | Y | N | N | |
private | N | Y | N | N | |
static | N | N | N | N | N |
final | Y | ||||
abstract | Y | ~ | ~ | ~ | |
synchronized |
抽象方法
抽象方法不能被声明为final和static
抽象方法的声明:public abstract sample();
静态方法
静态方法不能使用类的非静态变量。
静态方法中只能调用静态方法,不可调用非静态方法。
静态方法从参数列表得到数据,然后计算这些数据。
修饰符对方法的影响
项目 | 成员方法 | 静态方法 | 构造方法 | 抽象方法 |
---|---|---|---|---|
public | Y | Y | Y | |
default | Y | Y | Y | |
protected | Y | |||
private | Y | Y | Y | |
static | Y | ~ | N | |
final | Y | N | ||
abstract | Y | N | ~ | |
synchronized |
修饰符对变量的影响
项目 | 成员变量 | 静态变量 | 局部变量 |
---|---|---|---|
public | Y | Y | N |
default | Y | Y | N |
protected | Y | Y | N |
private | Y | Y | N |
static | Y | ~ | N |
final | Y | Y | N |
abstract | N | N | N |
synchronized | N | N | N |
参数
可变参数
可变参数的声明:typeName… parameterName
一个方法中只能指定一个可变参数
普通参数放最前面,可变参数放后面
Math 类
public class HelloWord {
public static void main(String[] args) {
System.out.println(Math.min(1,2));
}
}
继承
子类可以继承父类的所有公共方法和变量
父类声明为public的方法,子类中也必须是public
父类中声明为protected的方法,子类中要么是proected,要么是public。不能申明为private
父类中声明为private的方法,不能被继承
Final修饰的类不能被继承。