面向对象
什么是类
类是对现实生活中一类具有共同属性和行为的事物的抽象
类是对象的数据类型,类是具有想同属性和行为的一组对象的集合,简单理解:类就是对现实事物的一种描述
什么是对象属性
属性:对象具有的各种特征,每个对象的每个属性都拥有特定的值
什么是对象行为
对象行为是对象能够执行的操作
类和对象的关系
类:类是对现实生活中一类具有共同属性和行为的事物的抽象
对象:是能够看得到摸得着真实存在的实体
简单理解:类是对食物的一种描述,对象则是具体存在对象的抽象,对象是类的实体
类的组成
属性:在类中通过成员变量来体现(类中方法外的变量)
行为:在类中通过成员方法来体现(和前面的方法相比去掉static)
public class Phone{
String brand;
Double price;
public void call(){
System.out.println("我用"+price+"的"+brand+"打电话");
}
}
成员变量和局部变量的区别
区别 | 成员变量 | 局部变量 |
---|---|---|
位置不同 | 类中方法外 | 类中方法里 |
内存中位置 | 堆内存 | 栈内存 |
生命周期不同 | 随对象存在而存在,对象消失而消失 | 随方法调用存在而存在,方法结而消失 |
初始化值不同 | 有默认的初始化值 | 没有默认的,必须先定义赋值后使用 |
形参也是局部变量
成员的set中可以写条件
this关键字
指向该类
使用细节
- this关键字可以用来访问本类的属性、方法、构造器
- this用于区分当前类的属性和局部变量
- 访问成员方法的语句:this.方法名(参数列表)不管是否是静态,静态不能调用动态
- this不能在类定义的外部使用,只能在类定义的方法中使用
- 访问构造器语法:this(参数列表);注意只能在构造器使用(即只能在构造器中访问另一个构造器)必须放在第一条语句
package method;
/**
*参数为基本数据类型
**/
public class CanShuChuanZhi {
int age;
public CanShuChuanZhi() {
this(10);//在空构造器调用带参构造器,这句必须写在第一句
}
public CanShuChuanZhi(int age) {
this.age = age;
}
public static void main(String[] args) {
}
public void a(){
System.out.println("a");
}
public static void b(){
System.out.println("b");
this.a();//静态不能调用非静态
}
}
什么是继承
继承是面向对象的三大特征之一,可以使得子类具有父类的属性和方法,还可以在子类中重新定义,追加属性和方法
继承优缺点
-
好处:
提高了代码的复用性
提高了代码的维护性(如果方法需要修改,只改一处)
-
弊端
继承让类与类之间产生了关系,类的耦合性也增加了,当父类发生变化时,子类也不得不跟着变化,消弱了子类的独立性
什么时候使用继承
多个类之间存在相同属性
继承中变量的访问特点
在子类方法中访问一个变量:
子类局部范围找
子类成员范围找
父类成员范围找
如果都没有则报错
package classstady;
/**
*
**/
public class Son extends Parent{
public void a(){
String name = super.getName();//子类调用父类私有成员,需要使用super.getxxx()
}
}
super
super可以访问父类成员属性、方法、构造函数
继承中构造方法的访问特点
- 子类中所有的构造方法默认都会访问父类中的无参的构造方法
- 因为子类会继承父类中的数据,可能还会使用父类中的数据,所以子类初始化前,需要对父类进行初始化
- 每个子类构造方法的第一句默认都是:super()
如果父类中没有无参构造反复噶,只有带参构造方法,怎么办?
-
通过super关键字显示调用父类的有参构造器
-
父类中自己单独定义一个无参构造方法
继承中成员方法访问特点
先在子类中查找,子类没有父类找,父类没有报错
方法重写
子类出现和父类一摸一样的方法
当子类需要父类的功能,而功能主体中,子类有自己独特的内容,就可以通过重写父类中的方法,这样即延续了父类的功能,又定义了自己特有的内容
@Override
是一个注解
可以帮我们检查重写方法声明的正确性
方法重写注意事项
- (私有的方法不能被重写)父类中私有方法,子类不能被继承
- 子类方法访问权限不能比父类低(public>默认>私有的)
继承中的注意事项
java只支持单继承
java支持多层继承(孙子继承爸爸爸爸继承爷爷)
dos自动创建包
java -d. xxx.java
final和static
final修饰类,成员属性,成员方法
- final修饰类,无法被继承,可以继承其他类,所有方法默认final
- final修饰成员方法,无法被重写
- final修饰成员属性,该变量的值(必须初始化)无法被修改
- final不能用于修饰构造方法
package classstady;
/**
*
**/
public class ParentDemo {
public static void main(String[] args) {
final int age=10;
//age=10;//fianl修饰基本数据类型的局部变量,值不可以被修改
final Parent p=new Parent();
p.setName("111");
p.setName("111");
//p=null;//final修饰局部变量引用类型,引用地址不能被改变,地址存放的属性的值可以噶便
}
}
static
static可以修饰成员方法,成员变量
static修饰特点:被类的所有对象共享
static调用
不管是成员变量还是方法都可以用类名.属性名/方法名
static访问特点
非静态成员方法
- 能够访问静态成员变量
- 能够访问非静态成员变量
- 能够访问静态的成员方法
- 能够访问非静态的成员方法
静态的成员方法
- 能够访问静态的成员变量,但是不能够直接访问非静态的成员变量
- 能够访问静态的成员方法,不能够直接访问非静态的成员方法(需要创建对象后访问)
常量(不能被修改)
在其他地方也能访问
常量名大写(idea快捷键ctrl+shift+u)
public static final int CODE_200=200;
public static final int CODE_500=500;
main
执行时是jvm调用main
参数args是使用dos时 java xxx 参数1 参数2 参数3
多态
package duotai;
/**
*
**/
public class AnimalDemo {
public static void main(String[] args) {
Dog dog = new Dog();
Animal parent=new Dog();
parent.eat();//结果为子类的类容
}
}
多态访问特点
成员属性:编译看左边(父类有才能编译,没有报错),执行看左边
成员方法:编译看左边,执行看右边
package duotai;
/**
*父类
**/
public class Animal {
int age=20;
public void eat(){
System.out.println("父类");
}
}
package duotai;
/**
*子类
**/
public class Dog extends Animal{
int age=100;
/*
* 多态的条件:
* 有实现实现
* 方法重写
* 父类引用只想子类
* */
@Override
public void eat(){
System.out.println("我是狗");
}
}
package duotai;
/**
*
**/
public class AnimalDemo {
public static void main(String[] args) {
Dog dog = new Dog();
Animal parent=new Dog();
System.out.println(parent.age);//值是父类的属性值
System.out.println(dog.age);//子类的属性值
parent.eat();//子类
}
}
当我们需要使用不用子类的同一个方法时,我们创建方法时只需要参数写成父类就行,因为方法执行看右边,不管是哪个子类,只看出拿过来父类指向的子类
package duotai;
/**
* 父类
**/
public class Animal {
int age=20;
public void eat(){
System.out.println("父类");
}
}
package duotai;
/**
*猫
**/
public class Cat extends Animal{
public void eat(){
System.out.println("我是猫");
}
}
package duotai;
/**
*狗
**/
public class Dog extends Animal{
int age=100;
/*
* 多态的条件:
* 有实现实现
* 方法重写
* 父类引用指向子类
* */
@Override
public void eat(){
System.out.println("子类");
System.out.println(age);
}
}
package duotai;
import classstady.Parent;
/**
*操作
**/
public class App {
public void show(Cat cat){
cat.eat();
}
public void show(Dog dog){
dog.eat();
}
//使用多态一个代替所有子类
public void show(Animal animal){
animal.eat();
}}
package duotai;
/**
*测试
**/
public class Test {
public static void main(String[] args) {
App app = new App();
app.show(new Cat());//我是猫,Animal animal=new Cat();
app.show(new Dog());//我是狗,Animal animal=new Dog();
}
}
向下转型
// Animal animal = new Animal();
// Dog dog=(Dog) animal;//ClassCastException,类型转换异常
Animal animal1 = new Dog();
Cat cat=(Cat)animal1;//ClassCastException,类型转换异常
System.out.println(animal1 instanceof Animal);//true
System.out.println(animal1 instanceof Cat);//false
if(animal1 instanceof Dog){
Dog dog1=(Dog) animal1;//可以强转
dog1.eat();
}
抽象类
package ChouXiang;
/**
*抽象父类
**/
public abstract class AnimalParent {
public abstract void eat();
public void show(){
System.out.println("haha");
}//抽象方法可以有普通方法
}
package ChouXiang;
/**
*继承抽象类必须重写抽象类的抽象方法
**/
public class Dog extends AnimalParent{
@Override
public void eat() {
System.out.println("我是狗");
}
}
package ChouXiang;
/**
*继承抽象类必须重写抽象类的抽象方法
**/
public class Cat extends AnimalParent{
@Override
public void eat() {
System.out.println("我是猫");
}
}
package ChouXiang;
/**
*测试类
**/
public class Test {
public static void main(String[] args) {
AnimalParent animalParent = new AnimalParent() {
@Override
public void eat() {
System.out.println("我是父亲");
}
};
animalParent.eat();//我是父亲
animalParent.show();//haha
Dog dog = new Dog();
dog.show();//haha
dog.eat();//我是狗
Cat cat = new Cat();
cat.eat();//我是猫
}
}
抽象类的特点
- 抽象类中不一定有抽象方法,但是有抽象方法的一定是抽象类
- 抽象类不能实例化
- 抽象类由具体的子类进行实例化
- 子类必须对父类(抽象类)中的所有抽象方法进行重写
- 在抽象类中可以定义非抽象方法
- 子类如果不重写抽象类中的抽象方法,则该类还是抽象类
- 抽象类中可以有构造方法,用于子类访问父类时的数据初始化
- 抽象类可以定义成员属性
abstract关键字不能与那些关键字共存
private 冲突 abstract的方法必须被子类重写,而private不能被继承
final 冲突 final修饰的方法,变量都不能修改,而abstract修饰的方法必须被重写
static abstract没有方法体,没有意义
接口类
接口类的实现类要么重写接口中所有抽象方法,要么也是抽象类
package jiekou;
public interface Animal {
public void eat();
}
package jiekou;
import ChouXiang.AnimalParent;
/**
* 抽象类实现Animal不用实现抽象方法
**/
public abstract class DogImpl implements Animal {
}
package jiekou;
/**
*DogImpl的子类
**/
public class Dong extends DogImpl{
//必须实现所有抽象方法
@Override
public void eat() {
}
}
接口成员的特点
- 成员变量只能是常量;默认修饰符public static final
- 成员方法只能是抽象方法;默认修饰符public abstract
- 接口没有构造方法
- 接口中能否定义非抽象方法,jdk1.8后可以,加上default关键字public default void eat(),jdk1.8之前不可以
接口和类的区别
- 类和类的继承关系:类只能单继承,可以多层继承
- 类和接口的实现关系:可以单实现,可以多实现,还可以在继承一个类的时候多实现
- 接口和接口的继承:可以单继承,也可以多继承
抽象类和接口的区别
除了特点之外的区别
设计上的区别,抽象类是对事物的抽象(包括属性和方法),接口只对行为抽象
内部类
内部类可以直接访问外部类的成员(包括私有)
外部类想要访问内部类的成员,必须创建对象
package NeiBuLei;
/**
*
**/
public class Dog {
int age=10;
public class Dogsun{//内部类
String name="xiugou";
public void show(){
System.out.println(age);//内部类可以直接访问外部类的属性
}
}
public void show1(){
Dogsun dogsun = new Dogsun();
dogsun.show();//外部内调用内部类必须创建对象
System.out.println(dogsun.name);//xiugou
}
}
package NeiBuLei;
/**
*
**/
public class Test {
public static void main(String[] args) {
Dog dog = new Dog();
dog.show1();//10 //xiugou
//在其他类创建内部类的对象,需要先创建外部类的对下个再用外部类的对象.new 内部类
Dog.Dogsun dogsun = dog.new Dogsun();// Dog.Dogsun注意类型,
dogsun.show();
}
}
//企业实际开发中,不会让外界的类访问,将内部类私有化
# 内部类的分类
成员内部类(成员内部类,静态内部类)
局部内部类(方法内部类,匿名内部类)
如果内部类在方法外(成员内部类,加上static就是静态内部类)
如果内部类在方法内(局部内部类,方法内部类,匿名内部类)
成员内部类
package NeiBuLei;
/**
*
**/
public class Dog {
int age=10;
public class Dogsun{//成员内部类
String name="xiugou";
public void show(){
System.out.println(age);//内部类可以直接访问外部类的属性
}
}
public void show1(){
Dogsun dogsun = new Dogsun();
dogsun.show();//外部内调用内部类必须创建对象
System.out.println(dogsun.name);//xiugou
}
}、
外界访问 new waibu().new neibu()
静态内部类
有static关键字修饰的内部类为静态内部类
静态内部类访问外部类的成员变量或方法必须是静态的
外界访问格式 new 外部类.内部类()
package NeiBuLei;
import jiekou.DogImpl;
/**
*
**/
public class Dog {
static int age;//静态内部类访问外部类的成员必须是静态
public static class DogSun{
public void show(){
System.out.println(age);
}
}
public static void shows(){
DogSun dogSun = new DogSun();//外部类静态方法可以直接new
}
}
package NeiBuLei;
/**
*
**/
public class Test {
public static void main(String[] args) {
Dog.DogSun dogSun = new Dog.DogSun();
}
}
局部内部类
局部内部类定义在方法中,外界无法使用(方法外面无法使用),方法内访问需要在方法中创建对象
该类可以访问外部类的成员,也可以访问方法内的局部变量
匿名内部类
使用反编译工具可以看见匿名内部类本质还是实现了这个接口,只是名字为Null
AnimalParent animalParent = new AnimalParent() {
@Override
public void eat() {
System.out.println("我是父亲");
}
};
内部接口
public interface Map {
interface Entry{
int getKey();
}
void clear();
}
外部访问
public class MapImpl implements Map {
class ImplEntry implements Map.Entry{//Map.Entry{外部访问从这里看出调用内部接口是外部类或外部接口.内部接口
public int getKey() {
return 0;
}
}
@Override
public void clear() {
//clear
}
}
内部访问
class sdasa{
public interface Cart{
int UN_CHECKED=0;//购物车未选中状态
int CHECKED=1;//购物车选中状态
}
class ad implements Cart{
}
}
instanceof关键字
instanceof通过返回一个布尔值来指出,某个对象是否是某个特定类或者该特定类的子类的一个实例
1.如果Object是class的一个实例,则instanceof运算符返回true,如果object不是指定类的一个实例,或者object是null,返回false。class可以是类也可以是接口。
2.instanceof的编译状态和运行状态是有区别的
2.1在编译状态,class可以是object的父类,自身类,子类。在这三种情况下编译不会报错
2.2在运行状态时,class可以是object对象的父类,自身类,不能时子类。在前两种返回true,最后一种返回false。但是class子类时不会编译报错,运行结果为false。
字符串的遍历
public static void main(String[] args) {
String str="nuafa";
for (int i = 0; i < str.length(); i++) {
System.out.println(str.charAt(i));
}
}
replace()[替换]
- replace()方法用于将目标字符串中的指定字符(串)替换成新的字符(串)
- replaceFirst()方法用于将目标字符串中匹配某正则表达式的第一个字符串替换成新的字符串
- replaceAll()方法用于将目标字符串中匹配某正则表达式的所有子字符串替换成新的字符串
split()
遇到特殊符号使用\ \进行转意(* ^ |)
ascall
ascall码对应字符类型
计算机底层都是用二进制
'a'=64其实就是a的二进制0100 0001与64的二进制0100 0001
indexof
package finalxiushi1;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.util.Scanner;
/**
*
**/
public class son{
public static void main(String[] args) {
String str="nuafaAndafaAndafa";
System.out.println(str.indexOf(97));//2 返回97的位置。传int时按照ascall查找,97->a,查找a第一次出现的位置
System.out.println(str.indexOf("afa"));//2 返回第一次出现afa的位置.没有找到返回-1
System.out.println(str.indexOf("afa", 5));//8 返回从fromIndex开始第一次出现str的index,没有返回-1
}
}
元空间概念
1.8开始移除方法区,变成元空间
1.7开始常量池放到了堆空间
常量池
工具类设计
构造器私有化
方法静态
String转int
体哦阿健String存放的时数字
Integer.valueof("20");
自动装箱和自动拆箱
Integer a=60;//自动装箱,底层Integer.valueof
int b=a;//自动拆箱 底层intvalue
时间格式类
SimpleDateFormat simpleDateFormat = new SimpleDateFormat();
simpleDateFormat.format();//date->string
simpleDateFormat.parse();//string->date该方法必须写,字符串格式与格式化格式要匹配
二月多少天
package method;
import java.util.Calendar;
import java.util.Scanner;
/**
*二月份有多少天
**/
public class SecondMonthDays {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int year = scanner.nextInt();
Calendar instance = Calendar.getInstance();
instance.set(year,2,1);//xx年3月1号
instance.add(Calendar.DATE,-1);
int date = instance.get(Calendar.DATE);
System.out.println(date);
}
}
异常
finally是必须执行,但是遇到System.exit(),也不会执行
catch是顺序,父类不许写在最后
如果finally中有return,则执行finally的return
throw在那个方法,处理异常的throws就必须写在那个方法上、
package set;
/**
*
**/
public class Demo {
//Test2 extends Test
public static Test show(){
Test2 test2 = new Test2();
System.out.println("111");
return test2;//返回值可以是返回类型的子类
}
public static void main(String[] args) {
show();
}
}
代码块
静态代码块:
被static修饰,定义在类内部用户{}括起的代码块
构造代码块:没有被static修饰,定义在类内部,用户{}括起的代码块
普通代码块:定义在方法内部,用{}括起的代码块段
特征:
静态代码块:只能出现在类内,不允许出现在方法内
可以出现多次,按顺序在类加载时执行
无论该类实例化多少对象,只执行一次
无法在静态代码块声明静态变量,可以声明局部代码块,静态代码块中的声明,在外部无法进行访问
构造代码块:可以在类内出现多次,按顺序在每个对象实例化时执行
执行优先级,晚于静态代码块,高于构造方法
每次执行对象实例化,均会执行一次
不允许声明重复变量名
普通代码块:可以在方法内出现多次,按顺序在方法调用时执行
String
package method;
import javax.jws.soap.SOAPBinding;
import java.io.UnsupportedEncodingException;
/**
*
**/
public class StringToByte {
public static void main(String[] args) throws UnsupportedEncodingException {
String str="Hello,世界";
//String->byte
byte[] bytes = str.getBytes("UTF-8");
for (byte b :
bytes) {
System.out.print(b);
System.out.print(" ");
}
//byte->String
String s = new String(bytes);
System.out.println(s);
}
}
int a=9;
String b="gh";
String c="b"+a;//证明”“+int变量变为String
StringBuilder
StringBuilder和StringBuffer大致差不多,前者比后者效率高,后者比前者线程安全
StringBuilder的存在作用?
因为String的不可变性,容以创造大量得到不必要的String在常量池
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义