思想、思维方式 、思考问题的角度1.2 优点
复杂的问题简单化,更贴近现实生活中人类的思维角度1.3 面向对象与面向过程的区别
①面向过程就是分析出解决问题所需要的步骤,然后用函数实现、调用,关注过程; ②面向对象是把构成问题事务分解成各个对象,建立对象的目的不是为了完成一个步骤,而是为了描叙某个事物在整个解决问题的步骤中的行为,关注结果。 ③面向过程适用于执行者,面向对象适用于管理者2、类 2.1 类的定义 :
public class 类名{
//1.属性-> 成员变量
修饰符 数据类型 变量名 = 赋值;
修饰符 数据类型 变量名;
…
//2.功能-> 成员方法(不被static修饰)
public void|返回值类型 方法名(参数列表){
实现功能的代码;
[return 返回值;]
}
…
}
public class Class_Car {
public String brand;
public String color;
public double price;
public void drive(){
System.out.println("一辆"+price+"的"+color+"的"+brand+"即将开始旅程");
}
}
3、对象
3.1 导包
指明要使用类型的位置 注意:不需要导包的类型: 1)java.lang下 2)同包下的类3.2 创建对象
引用数据类型 变量|引用 = new 引用数据类型();
new关键字具有创建对象的能力
3.3 使用属性|功能 引用.属性
引用.功能名字(参数列表)
public class Class_CarTest{
public static void main(String[] args){
//创建对象
Class_Car car=new Class_Car();
//赋值
car.brand="奔驰";
car.color="黑色";
car.price=500000;
//调用
car.drive();
}
}
***注意:***
1)new关键字创建对象的步骤:
①在堆中为对象开辟空间,同时成员变量跟随对象进入堆内存,并赋默认值
②调用构造器为对象初始化信息
③将地址返回给引用
2)成员变量只声明不赋值存在默认值
整数0 小数0.0 boolean:false char:空字符 引用数据类型: null
3)先有类才能创建对象,有了对象才有了成员变量,才能使用成员
4、构造器(构造函数、构造方法)
4.1 作用
为对象初始化信息(为对象的成员变量赋值)
4.2 使用 跟随new关键字一起使用,不能单独调用
4.3 定义 修饰符 类名(参数列表){ }
4.4 用例
public class Class03_ComputerTest {
public static void main(String[] args){
//创建对象的同时为成员变量赋值
Computer c=new Computer("联想",5000);
c.run();
}
}
class Computer{
String brand;
double price;
//带参构造器
public Computer(String pcbrand,double pcprice){
if(pcprice<0){
System.out.println("价格不合法无法初始化...");
return;
}
brand=pcbrand;
price=pcprice;
}
public void run(){
System.out.println("一台"+brand+"电脑正在运行");
}
}
注意:
①构造器不能定义void|返回值
②构造器也是特殊的方法,具有方法重载的特性->构造器的重载
③如果一个类中没有显示的定义构造器,编译器会自动默认提供一个空构造(没有参数的构造器)
④如果存在显示定义的构造器,编译器不会再为类型提供任何构造器了,包括空构造
⑤构造器中可以存在return,根据需求定义,实现提前结束构造器,但是不能带出返回值
⑥构造器帮助实现,在通过new关键字创建对象的同时为对象初始化信息
⑦ 以后定义模板类,至少提供一个空构造,按需提供带参构造
1)局部变量需要声明且初始化之后才能被正常使用
2)成员变量可以声明之后直接使用,不同的数据类型作为成员变量Java都会给一个默认值
(所有的整数 都是 0 byte、short、int 、long
所有的浮点数 都是 0.0 float double
boolean类型的默认值是 false
char类型的默认值是 空格
所有引用类型的默认值都是 null )
5.2 位置 1)局部变量是在方法中或者时代码块中
2)成员变量而言声明在类中方法外
5.3 作用域 1)局部变量而言,在声明开始都 方法或者时代码块结束为止
2)成员变量,整个类中都有效
5.4 调用方式 1)局部变量而言,在方法中直接通过变量名直接使用
2)成员变量而言: 在当前成员变量前加static修饰 此时可以直接在static修饰的方法中直接使用
6、this关键字 6.1 this. 指代当前new的对象
区分局部与成员同名问题
默认就近原则
存在同名问题,指代成员需要通过this.调用
不存在同名问题时候,指代成员直接使用省略this.
6.2 this(参数列表) 在构造器的首行用来调用本类中其他构造器
注意:
1)不能多个构造器之间通过this相互调用
2)this存储指代对象的地址
3)在构造器中遇到this指代对象,默认代表当前new的对象
4)在成员方法中的this默认指代调用成员方法的对象
5)this不能使用在static修饰的方法中
6.3 用例public class Class04_This {
public static void main(String[] args){
//匿名对象 : 只能在当前行使用一次
new People("张三",12,true).info();
People p=new People("lisi",18);
System.out.println(p);
p.info();
}
}
class People{
public String name;
public int age;
public boolean sex;
//两个参数的构造器
public People(String name,int age){
this();
this.name=name; //在构造器中遇到this指代对象,默认代表当前new的对象
this.age=age;
System.out.println(name+"……"+age+"……");
}
public People(){
System.out.println("空参");
}
//三个参数的构造器
public People(String name,int age,boolean sex){
//this(参数列表):调用同类
this(name,age);
this.sex=sex;
System.out.println(name+"……"+age+"……"+sex);
}
//在成员方法中的this默认指代调用成员方法的对象
public void info(){
String name = "xixihaha";
System.out.println(name+"-->"+this.age+"--->"+sex);
}
}
7、static
7.1 定义
static 静态的 成员修饰符: 只能修饰成员不能修饰局部!!!
修饰变量 : 静态变量|类变量
修饰方法 : 静态方法|类方法
修饰块 : 静态块
修饰类 : 静态内部类
1)类名.静态变量名
类名.静态方法名(参数列表)
2)对象.静态变量名
对象.静态方法名(参数列表)
注意:
1)静态的是属于类的!!
2)成员是属于对象的,只能跟随对象使用!!
3)成员变量存在与对象的内存空间中,有多少对象的堆内存空间,就存在多少份成员变量
4)静态的变量是独一份的,当前类的多个对象共享的,存在与静态区中
5) 先静态后成员!!
6)在静态内容中使用: 只能直接使用静态内容,不能直接使用成员内容,需要跟随对象使用成员
7)在成员内容中使用: 可以直接使用成员,可以直接使用静态
public class Class01_Static {
static int i=5;//静态变量
int j=3;//成员变量
public static void main(String[] args) {
//局部变量
int i=1;
//类名调用静态内容
System.out.println(Class01_Static.i);
Class01_Static.test1();
//对象
Class01_Static st=new Class01_Static();
//只能通过对象调用成员
System.out.println(st.j);
st.test2();
//对象调用静态内容
System.out.println(st.i);
st.test1();
}
//静态方法
public static void test1(){
System.out.println("这是一个静态方法");
}
//成员方法
public void test2(){
System.out.println("这是一个成员方法");
}
}
8、block块
8.1 定义
{ } : 自成作用域
8.2 分类 1)局部代码块:定义在方法中或语句块中
2)构造块:定义在类中方法外
3)静态块:定义在类中方法外
4)同步块
注意:
1)构造块中的代码会先于构造器中的代码之前执行,在编译期间构造块中的代码会被编译到要执行的构造器代码的最上面
2)如果存在多个构造块,从上到下一次执行
3)静态块会在类第一次加载完成之后进行执行,并且只执行一次
4)如果存在多个静态块,从上到下一次执行
5)构造块作用 : 为成员提供默认初始化
6)静态块作用 : 1)为静态内容提供默认的初始 2) 基础设置等的加载(数据库的驱动…)
8.3 用例public class Class02_Block {
static int i=8;
//静态块:类第一次加载时执行
static{
System.out.println("我是静态块");
}
//构造块:跟随new一起使用
{
System.out.println("我是构造块");
}
//构造器
public Class02_Block(){
System.out.println("我是构造器");
}
public static void main(String[] args){
//局部代码块:跟随方法的调用
{
System.out.println("我是局部代码块");
}
System.out.println(i);
new Class02_Block();
}
}
9、debug
调试工具
9.1 作用 1.追踪程序的执行流程
2.定位异常出现的位置
3.观察程序执行过程中变量的变化情况
4.根据追踪程序的执行流程学习第三方框架的源码
1、设置断点
在行号的后面鼠标单击设置断点
2、Debug运行
3、debug运行模式下进行调试
Step over F8 : 下一步跳过|略过
如果下一步是方法的调用,不会跟随方法的调用执行,直接进入下一步
Step into F7 : 步入 | 下一步进入
如果下一步是自定义方法的调用,跟随方法的调用执行每一步
Step out shift+f8 : 下一步调出
如果在方法的内部,下一步直接调出到方法调用处
Force step into alt+shift+f7 : 下一步强制进入
如果下一步是方法的调用,包括jdk源码方法的调用,强制进入,跟随执行
Run to Cursor alt+F9 : 直接运行到鼠标光标所在位置
文件夹
帮助管理众多的资源
提供了多重命名空间
存在与java文件的最上面首行,标识当前类型所在的包路径
10.3 导包 指明要使用类型的位置
如果要使用其它类型,可能涉及到导包问题
1)java.lang包下的内容
2)同包类
1.使用的位置指定类型的全限定名 : 包名.类名
只能在当前位置使用一次,简单方便,但是使用频繁的话建议使用import导包
2.import关键字进行导包
定义语法 : import 包名.类名;
位置: 类的上面,package信息下面
3.模糊匹配
模糊匹配当前报下要使用的所有类型
只会降低编译效率,不会降低运行效率
4.静态导入 import static
导入一个类型中的静态内容
注意:
以后项目中需要先定义包后定义类型
package com.oop01;
import java.util.*;
import static java.lang.Math.PI;
import static java.lang.Math.round;
public class Class04_import {
public static void main(String[] args) {
Scanner sc2 = new Scanner(System.in);
Random ran = new Random();
ArrayList list = new ArrayList();
System.out.println(PI);
System.out.println(round(1.4));
}
}
11、private
11.1 定义
private 私有的,成员修饰符(只能修饰成员不能修饰局部)
数据的安全隐患问题时 解决 : private 私有的
一旦被private关键字修饰的成员只能在当前类中使用
私有的属性需要配合一对公共的访问方式
设置器 setter : 成员方法,为私有属性设置值
访问器 getter : 成员方法,获取私有属性的值
11.2 用例public class Class05_Private {
public static void main(String[] args) {
People p=new People();
p.setName("zhangsan");
p.setAge(12);
p.info();
}
}
class People{ //类是公共的
private String name; //属性私有化
private int age;
public People(){ //至少提供一个空构造
}
//设置器
public void setName(String name){ //提供一对公共的访问方式
this.name=name;
}
//访问器
public String getName(){
return name;
}
public void setAge(int age){
this.age=age;
}
public int getAge(){
return age;
}
public void info(){
System.out.println(name+"……"+age);
}
}
注意:
以后定义的实体类要求属性全部私有化,并根据需求提供一对公共的访问方式
12、面向对象的三大特性封装 继承 多态12.1 封装:
1、隐藏内部的实现细节,对外提供公共的访问方式
2、优点:①提高安全性②提高代码的复用性
3、问题: 私有是封装,是封装一个具体的体现
封装不仅仅是私有,类,方法,属性私有化…
12.2 继承 子承父业
JAVABEAN : 对对象的抽象,抽出像的部分定义在javabean类中
父类 : 抽出子类像的部分定义在父类中,达到类层面的简化
1、作用:提高代码的复用性
2、使用:子类 extends 父类
父类 | 基类 | 超类 : 被继承的类
子类 | 派生类 : 继承父类的类
3、注意:①子类一旦继承父类,有权使用父类的成员
②子类中可以扩展子类独有的内容
③单继承机制(简单,不够灵活不便于后期维护)
面向对象的设计原则之一: 开闭原则 : 对修改关闭对扩展开放
public class Class01_Extends {
public static void main(String[] args) {
Cat cat=new Cat();
cat.name="java";
cat.age=1;
cat.sleep();
cat.eatfish();
Dog dog=new Dog();
dog.name="小胖";
dog.age=2;
dog.sleep();
dog.lookdoor();
}
}
//父类
class Animal{
String name;
int age;
public void sleep(){
System.out.println(name+"睡觉");
}
}
//子类
class Cat extends Animal{
public String color;
public void eatfish(){
System.out.println(age+"个月的"+name+"爱吃鱼");
}
}
class Dog extends Animal{
public void lookdoor(){
System.out.println(age+"岁的"+name+"在看家");
}
}
12.3 多态
1、多态 : 一种事物的多种形态|多种表现形式 ,行为多态
2、表现形式:父类的引用指向子类类型的对象
3、前提:继承|实现
4、调用:
调用子类中重写的方法
只能调用父类中存在的成员,对子类新增内容不可见
注意: 正常的情况都应该为对应类型的数据赋值给对应类型的变量, 除了当前满足多态时候,才能够实现对应类型的数据赋值给了其他类型的引用,要求其他类型必须为对象的父类类型
5、多态调用成员的特点:
成员变量: --> 不存在多态
编译运行看父类
编译运行看左边
编译运行看类型
成员方法: --> 行为才有多态
编译看父类,运行看子类
编译看类型
编译看左边
多态如果不配合方法的重写,多态没有意义
父类引用指向不同的子类对象,当子类中存在重写,对功能实现方式可能不同,这是行为多态的体现,同一个功能的不同实现方式
public class Class07_Poly {
public static void main(String[] args) {
People p=new People();
Student s=new Student();
People p1=new Student(); //父类的引用指向子类类型的对象
System.out.println(p1.name); //只能调用父类中存在的成员
p1.test(); //调用子类中重写的方法
}
}
class People{
String name="people";
public void test(){
System.out.println("people");
}
}
class Student extends People{
String name="student";
public void test(){
System.out.println("student");
}
}
13、javabean规范
1、类是公共的
2、至少提供一个空构造
3、私有的属性
4、公共的访问方式
5、重写toString与equals方法
public class User {
private String name;
private int age;
public User() {
}
public User(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "User{" +
"name='" + name + ''' +
", age=" + age +
'}';
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
User user = (User) o;
return age == user.age && Objects.equals(name, user.name);
}
}
14、super
1、super 与 this 之间的区别
this : 指代当前new的对象
1)能够使用在构造器的首行调用本类中的其他构造器
this(参数)
2)区分同名的局部与成员问题
super : 指代父类对象
1)能够在子类构造器的首行调用父类的指定构造器
super(参数)
如果没有显示调用父类的指定构造器,默认调用父类空构造
在 子类构造器的首行不能同时显示定义this()与super()
2) 区分子类与父类同名成员问题
默认就近原则,有局部找局部,没有局部找子类,都没有顺着继承体系到父类中找成员
如果想要找子类this.调用子类成员,但是如果没有局部与成员同名问题,this.可以省略
如果想要找父类super.调用父类成员,如果没有子类与父类与局部同名问题,super.可以省略
2、注意:
创建子类对象,会创建父类对象后创建子类对象–> 先父类后子类
静态内容中不能使用this与super
public class Class03_Super {
public static void main(String[] args) {
Son son=new Son(12);
son.test();
}
}
class Father{
int i=0;
int j=5;
public Father(){
System.out.println("父类 空构造");
}
public Father(int i){
System.out.println("父类 一个参数的构造器");
}
}
class Son extends Father{
int j=3;
public Son(){
System.out.println("子类 空构造");
}
public Son(int i){
System.out.println("子类 一个参数的构造器");
}
public void test(){
int j=1;
System.out.println(j); //局部就近原则
System.out.println(this.j); //子类成员
System.out.println(super.j); //父类成员
System.out.println(i); //相当于省略了super.
}
}
15、重写
1、重写 与 重载 : 都是方法的特性
重载:
①同一个类中的多个方法
②.方法名相同
③方法签名(参数列表不同)
重写 :
①不同的两个类
②继承|实现
③方法签名相同
2、重写前提:
子类对从父类中继承的某功能,功能满意,功能的实现不满意,这个时候可以在子类中对于这个功能进行重写,重新实现
注意:
子类中一旦对父类中的某个功能进行重写,在调用时候回对父类的功能进行屏蔽,调用子类中重写的方法
子类对象在调用的时候,子类有重写调用子类的,子类没有重写,调用父类
3、检查是否为重写方法:
①在行号的后面存在O重写标识
②@Override 强制检测方法为重写方法
4、重写的满足的三个细节条件:
== 方法签名
<= 返回值类型
如果返回值类型为基本数据类型|void,要求完全相等
如果返回值类型为引用数据类型 : 要求子类中的重写方法返回值类型<=父类中被重写方法的返回值类型
>= 权限修饰符
子类中重写方法的权限修饰符>=父类中被重写方法的权限修饰符
5、不能被重写的方法:
被private修饰的方法不能被重写,被private修饰的成员可以被继承,但是无权限访问
被final修饰的方法不能被重写
被static修饰的方法不能被重写
如果子类中存在与父类静态方法同名的方法,要求子类中的同名方法也为static才可
方法签名: 是方法的唯一标识 方法名+参数列表
public class Class04_Override {
public static void main(String[] args) {
Rose rose=new Rose();
rose.test();
new Flower().test();
}
}
class Flower{
String color;
String type;
public Flower(){ }
void test(){
System.out.println("花儿开了");
}
}
class Rose extends Flower{
@Override //重写
void test(){
System.out.println("玫瑰开了");
}
}
16、final
final 最终的 成员修饰符
被final修饰的变量为常量
被final修饰的方法不能被重写
被final修饰的类不能被继承–>太监类
注意:
基本数据类型的变量=右边为数据值
引用数据类型的变量=对象,对象的地址值
public class Class05_Final {
static final Person P=new Person();
static final int AGE=1;
static final String NAME="";
public static void main(String[] args) {
// P=new Person();
P.age++;
System.out.println(P.age);
}
}
class Person{
int age;
String name;
}
17、object
1、Object 老祖宗 java.lang.Object
是java中所有类的父类
一个类如果没有显示的继承其他父类,就会默认的继承自Object
java中所有类都会显示或者隐式的继承自Object
Object类中定义的成员是所有子类,子类对象都可以使用的(不考虑权限修饰符问题)
2、Object类中常用的方法:
1) toString : 返回对象的字符串表现形式
在打印一个对象的引用时,默认输出为当前对象的toString方法的返回值
public String toString() {
return getClass().getName() + “@” + Integer.toHexString(hashCode());
}
Object类中toString默认返回对象的包名.类名@十六进制地址值
在业务需求下,我们想要输出对象的基本信息(成员变量的值)–> 在子类中重写从父类中继承的toString,子类对象调用的时候回调用重写后的方法
2) equals : 比较两个对象是否相等
== : 比较是否相等
比较基本数据类型数据值是否相等
比较引用数据类型的地址值是否相等
Object类中的equals的实现: 默认比较对象的地址值
public boolean equals(Object obj) {
return (this == obj);
}
子类中重写equals方法,实现比较对象内容(成员变量的值)非地址值
3、== 与 equals 之间的区别?
==可以比较基本数据类型|引用数据类型,比对象地址
equals默认Object类中比较对象地址,因为内部通过==实现比较
可以通过在子类中重写equals实现比较对象内容
public class Class06_Object extends Object{
public static void main(String[] args) {
Pang dog1=new Pang("小胖",2,"黄色");
Pang dog2=new Pang("小胖",2,"黄色");
System.out.println(dog1);
System.out.println(dog2);
System.out.println(dog1.equals(dog2));
}
}
class Pang{
String name;
int age;
String color;
public Pang(String name,int age,String color){
this.name=name;
this.age=age;
this.color=color;
}
@Override //重写toString方法
public String toString(){
return name+"今年"+age+"岁了,它的颜色是"+color;
}
//重写equals方法
public boolean equals(Object obj) {
if(this==obj){
return true;
}
if(obj instanceof Pang){
Pang pangObj=(Pang)obj;
if((this.name).equals(pangObj.name)&&(this.age)==(pangObj.age)&&(this.color).equals(pangObj.color)){
return true;
}
}
return false;
}
}
18、权限修饰符
访问权限修饰符
| 本类 | 同包类 | 不同包类下的子类 | 不同包下的其他类 | |
|---|---|---|---|---|
| public 公共的 | √ | √ | √ | √ |
| protected 受保护的 | √ | √ | √ | |
| default 默认的 | √ | √ | ||
| private 私有的 | √ | √ |
成员修饰符,只能修饰成员不能修饰局部的
能够修饰类的: public default
父类中被protected修饰的成员,在不同包下的子类中通过继承关系可以使用
常用的: public private
public class Class02_Modifier {
public String testPublic="public";
protected String testProtected="protected";
String testDefault="default";
private String testPrivate="private";
public static void main(String[] args) {
}
//本类
public void test(){
System.out.println(testPublic);
System.out.println(testPrivate);
System.out.println(testDefault);
System.out.println(testProtected);
}
}
19、转型
多态调用对子类新增内容不可见
转型: 类型转换
KongZiDie zi = new KongZi(); 多态
zi.teach(); 子类中重写的方法
父类引用 转为对应的子类类型
KongZi z = (KongZi)zi; //KongZi z = new KongZi();
z.play();
ClassCastException : 类型转换异常,在向下转型时候转为非其他子类类型 -> Brother z = new KongZi();
19.3 instanceof 运算符 : 避免在转型的时候遇到类型转换异常的出现,在转型之前先判断
引用 instanceof 类型 :
判断前面的引用是否是指向后面类型的对象|子类对象 如果是返回true,不是返回false
public class Class01_Cast {
public static void main(String[] args) {
//向上转型
KongZiDie d=new KongZi();
d.teach();
//向下转型
if(d instanceof KongZi){
KongZi z=(KongZi) d;
z.teach();
z.play();
}else if(d instanceof Brother){
Brother b=(Brother) d;
b.teach();
b.play();
}
System.out.println(d instanceof KongZiDie); //true
System.out.println(d instanceof KongZi); //true
System.out.println(d instanceof Brother); //false
System.out.println(d instanceof Object); //true
System.out.println("main结束了");
}
}
class KongZiDie{
public void teach(){
System.out.println("做生意");
}
}
class KongZi extends KongZiDie{
//重写
public void teach(){
System.out.println("论语");
}
//新增内容
public void play(){
System.out.println("lol");
}
}
class Brother extends KongZiDie{
public void teach(){
System.out.println("敲代码");
}
public void play(){
System.out.println("绝地求生");
}
}
20、抽象abstract
抽象类: abstract抽象的
被abstract修饰的类 -->抽象类
被abstract修饰的方法 -->抽象方法
没有方法体
抽象方法必须定义与抽象类中
注意:
1.抽象类不能实例化
2.抽象类中可以定义抽象方法,可以定义非抽象方法,属性,构造器…
3.抽象方法必须定义与抽象类中
4.抽象类的使用: 通过具体子类对象调用
具体子类 : 重写所有的抽象方法 + 按需新增
抽象子类 : 按需重写抽象方法 + 按需新增
5.一个抽象方法如果一旦被重写,后续的子类中可以不再重写,可以按需重写
6.抽象方法必须要被重写,没有重写,没有方法体,不能调用
7.abstract不能与static,private,final与native一起使用
public class Class02_Absrtact {
public static void main(String[] args) {
Java java=new Java();
System.out.println(java.i);
java.work();
java.work2();
java.sleep();
Demo d = new Demo();
d.work2();
d.work();
d.test();
//多态
Develop develop = new Java();
develop.work();
}
}
abstract class Develop{
//属性
int i=1;
static int j=5;
//抽象方法体 : 方法体不知道定义什么,不确定如何定义,那就不定义
abstract void work();
abstract void work2();
//普通方法
void test(){
System.out.println("抽象类中的普通方法");
}
}
//具体子类
class Java extends Develop{
//重写
@Override
void work() {
System.out.println("服务器端开发");
}
@Override
void work2() {
System.out.println("Java中重写的work2");
}
//新增
void sleep(){
System.out.println("睡觉");
}
}
//抽象子类
abstract class Db extends Develop{
@Override
void work() {
System.out.println("数据处理");
}
}
class Demo extends Db{
@Override
void work2() {
System.out.println("Demo中重写的work2");
}
}
21、接口
21.1 接口
特殊的抽象类
接口是一个引用数据类型
接口为抽象功能的集合
类单继承机制,接口是多实现机制
接口定义开发规范
解耦,降低耦合度
interface 定义接口
接口->通过implements实现接口
父类->需要通过extends继承父类
子类继承父类, 就可以直接有权使用父类中的成员(侧重点:直接拿过来就用)
实现类实现接口, 实现类就拥有了接口定义的功能,但是功能都是抽象的,没有方法体的,需要实现类自己去实现的(侧重点在于方法的实现,称为实现类)
jdk1.7及之前
1).公共的静态的常量 public static final -> 任意省略
2).公共的抽象的方法 public abstract -> 任意省略
jdk1.8及之后,对接口中新增:
1).静态方法: 只能通过接口名调用,不同通过实现类对象调用
2).默认方法: 被default关键字修饰的方法 只能通过实现类对象调用
public class Class05_Interface {
public static void main(String[] args) {
MyInterface1.testStatic();
new Impl3().testDefault();
}
}
interface MyInterface1{
public static void testStatic(){
System.out.println("接口中的静态方法");
}
public default void testDefault(){
System.out.println("接口中的默认方法");
}
}
//实现类
class Impl3 implements MyInterface1{
}
21.4 使用
1.接口不能实例化
2.需要通过实现类实现接口使用
具体的实现类: 重写所有的抽象方法 + 按需新增
抽象的实现类: 按需重写抽象方法 + 按需新增
3.类只能被类继承,接口只能被类实现
4.类只能单继承父类,但是可以实现多个接口
5.先继承父类后实现接口
6.一个接口可以继承多个接口,接口可以多继承接口
7.避免实现的多个接口中存在相同的方法
public class Class03_Interface {
public static void main(String[] args) {
System.out.println(MyInterface.PI);
Impl1 i=new Impl1();
i.haha();
i.hehe();
}
}
//接口
interface MyInterface{
double PI=3.14;
void haha();
void hehe();
}
//具体的实现类
class Impl1 implements MyInterface{
@Override
public void haha() {
System.out.println("哈哈哈哈");
}
@Override
public void hehe() {
System.out.println("嘻嘻嘻嘻嘻嘻");
}
}
//抽象的实现类
abstract class Impl2 implements MyInterface{
@Override
public void haha() {
}
}
//具体的子类, 一个抽象方法如果一旦被重写,后续的子类中可以不再重写,可以按需重写
class son extends Impl2{
@Override
public void hehe() {
}
}
public class Class04_Interface extends Object implements D{
@Override
public void a() {
}
@Override
public void b() {
}
@Override
public void c() {
}
}
interface A{
void a();
}
interface B{
void b();
}
interface C{
void c();
}
interface D extends A,B,C{
}
22、数组
22.1 一维数组
数组中放数据
1、数组:
相同数据类型有序的集合
2、作用:
数组: 存储多个数据
变量: 存储单个数据
3、特点:
1)定长,长度一旦确定不可改变
2)存储相同数据类型的数据
3)有序,有索引
4)引用数据类型
4、数组长度:
数组名 .length
5、操作数组:
根据索引操作数组
数组名[索引]
索引: 从0开始,依次+1
6、数组的遍历:
普通for
for(int i=0;i<=arr.length-1;i++){ -->i作为索引
}
增强for
for(String str : arr){ --> str数组中的每一个数据
}
public class Work01_ArrayPractice {
public static void main(String[] args) {
int[] arr={4,2,8,0,1,5,0,7,10};
System.out.println(find(arr,8));
System.out.println(Arrays.toString(check(arr)));
System.out.println(Arrays.toString(change(new char[]{'A','B','d'})));
}
public static int find(int[] arr,int value){
for(int i=0;i< arr.length;i++){
if(arr[i]==value){
return i;
}
}
return -1;
}
public static int[] check(int[] arr){
int count=0;
for(int i=0;i< arr.length;i++){
if(arr[i]!=0){
count++;
}
}
if(count== arr.length){
return arr;
}
int[] newarr=new int[count];
int j=0;
for (int i = 0; i < arr.length; i++) {
if(arr[i]!=0){
newarr[j++]=arr[i];
}
}
return newarr;
}
public static char[] change(char[] arr){
for(int i = 0; i < arr.length; i++){
if(arr[i]>='A'&&arr[i]<='Z'){
arr[i]+=32;
}
}
return arr;
}
}
22.2 二维数组
二维数组 : 了解
数组中放数组
1、声明 :
数据类型[][] 数组名; --> 推荐
数据类型 数组名[][];
数据类型[] 数组名[];
2、初始化 : 创建及第一次赋值
1)动态初始化 : 先创建数组,后赋值
数据类型[][] 数组名 = new 数据类型[外层二维数组的长度][内层的每一个一维数组的程度];
数据类型[][] 数组名 = new 数据类型[外层二维数组的长度][];
数组名[二维索引] = new 数据类型[一维长度];
...
2)静态初始化 : 创建数组的同时赋值
数据类型[][] 数组名 = new 数据类型[][]{{1,2,3},{4,5},{6}...};
数据类型[][] 数组名 = {{1,2,3},{4,5},{6}...};
3、使用
根据索引操作
二维数组名[二维的索引][一维的索引]
4、遍历
1)双重for循环嵌套
外层for循环遍历外层的二维数组,内存for循环用来遍历内层的每一个一维小数组
2)增强for与普通for相互嵌套
普通-->普通
普通-->增强
增强-->增强
增强-->普通
public class Class01_Array {
public static void main(String[] args) {
//动态初始化
int[][] arr=new int[2][3];
arr[0][0]=1;
arr[0][1]=2;
arr[0][2]=3;
arr[1][0]=4;
arr[1][1]=5;
arr[1][2]=6;
System.out.println(arr[0][0]);
System.out.println(arr[0][1]);
System.out.println(arr[0][2]);
System.out.println(arr[1][0]);
System.out.println(arr[1][1]);
System.out.println(arr[1][2]);
//动态初始化
char[][] arr1=new char[2][];
arr1[0]=new char[3];
arr1[1]=new char[2];
arr1[0][0]='a';
arr1[0][1]='b';
arr1[0][2]='c';
arr1[1][0]='d';
arr1[1][1]='e';
System.out.println(arr1[0][0]);
System.out.println(arr1[0][1]);
System.out.println(arr1[0][2]);
System.out.println(arr1[1][0]);
System.out.println(arr1[1][1]);
//静态初始化
String[][] arr2=new String[][]{{"中","国"},{"你","好","啊"}};
String[][] arr3={{"中","国"},{"你","好","啊"}};
System.out.println(Arrays.deepToString(arr2));
//遍历
//普通嵌套普通
for(int i=0;i< arr2.length;i++){
for (int j=0;j
23、内部类
了解,理解
1、类中定义类
2、内部类的分类:
成员内部类
静态内部类
私有内部类
局部内部类
匿名内部类 ***
lambda表达式******
23.1 成员内部类
内部类定义在外部类的成员位置
当一个类的成员也是另外一种事物,这个成员可以定义为内部类
成员内部类也是类具有类的特点,能够继承父类,能够实现接口,也具有成员的特点,可以被成员修饰符修饰
注意:
只有静态内部类中才能定义静态内容,其他内部类中不能定义静态内容除了静态常量
成员内部类中可以直接使用外部类中的成员,包括私有的
外部类中需要通过成员内部类的对象方法成员内部类的成员
其他类中使用成员内部类中的成员需要通过外部类对象构建内部类对象,通过内部类对象调用内部类成员
Class001_Outer.Inner in = new Class001_Outer().new Inner();
public class Class03_Outer {
//成员位置: 类中方法外
private int a=5;
private static int b=7;
//成员内部类
public class Inner extends Object{
//成员内部类中的属性
int i=0;
static final int j=1;
//成员内部类中的功能
public void inner(){
System.out.println("成员内部类中的成员方法inner");
System.out.println(i);
System.out.println(j);
System.out.println(a);
System.out.println(b);
}
}
//外部类中的成员方法
public void outer(){
System.out.println("外部类中的成员方法outer");
//创建内部类中的对象访问内部类的成员
Inner in=new Inner();
System.out.println(in.i);
System.out.println(in.j);
System.out.println(a);
System.out.println(b);
in.inner();
}
}
23.2 私有内部类
通过private修饰的成员内部类
私有内部类中可以直接使用外部类中的私有成员
外部类中可以通过私有内部类的对象调用私有内部类中的成员,包括私有的
私有内部类只能在外部类中使用,其他类中无法使用
public class Class05_OuterPrivate {
private int i=1;
private static int j=2;
private class Inner{
private int a=3;
private static int b=4;
public void inner(){
System.out.println("私有内部类中的成员方法");
System.out.println(i);
System.out.println(j);
}
}
public void outer(){
Inner in=new Inner();
System.out.println(in.a);
System.out.println(in.b);
in.inner();
}
}
23.3 静态内部类
静态内部类中可以直接定义静态内容
在静态内部类中使用外部类中的成员需要通过外部类对象使用,因为内部类是静态的,使用外部类中的静态内容,可以直接使用
外部类中需要通过静态内部类的对象调用静态内部类的成员,可以通过静态内部类的类名.调用静态内部类的静态内容
其他类中使用静态内部类中的静态内容,通过外部类的类名.静态内部类的类名.调用静态内容
其他类中使用静态内部类中的成员内容,通过new 外部类的类名.静态内部类的类名的对象.调用成员内容
public class Class06_OuterStatic {
private int i=1;
private static int j=2;
static class Inner{
int a=3;
static int b=4;
//成员方法
public void Inner1(){
System.out.println("静态内部类中的成员方法");
System.out.println(a);
System.out.println(b);
System.out.println(new Class06_OuterStatic().i);
System.out.println(j);
}
//静态方法
public static void Inner2(){
System.out.println("静态内部类中的静态方法");
Inner in=new Inner();
System.out.println(in.a);
System.out.println(b);
System.out.println(new Class06_OuterStatic().i);
System.out.println(j);
}
}
//外部类中的成员方法
public void Outer(){
System.out.println("外部类中的成员方法");
System.out.println(Inner.b);
System.out.println(i);
System.out.println(j);
Inner.Inner2();
Inner in=new Inner();
in.Inner1();
}
}



