专栏目录
文章目录
一、递归
定义:方法调用自身,称之为递归方法
要求:
1.递归方法应该具备跳出逻辑:java.lang.StackOverflowError
2.调用自身时传递的参数需要具备规律
public class Java16_Object_Recursion {
public static void main(String[] args) {
/*
求20以内的奇数和
1+3+5+7+9+11+13+15+17+19
计算是有边界的
*/
int result = computeAP(10);
System.out.println(result);
System.out.println("===========================");
/*
阶乘:5! => (4,3,2,1) => 5*4*4*3*2*1
0的阶乘为1
一个大于1的数的阶乘等于这个数-1的阶乘
*/
int result2 = computeFactorial(5);
// int result2 = computeFactorial(50000); 报错:java.lang.StackOverflowError
System.out.println(result2);
}
public static int computeAP(int num) {
num = num % 2 == 0 ? num - 1 : num;
if (num == 1) {
return 1;
} else {
return num + computeAP(num - 2);
}
}
public static int computeFactorial(int num) {
if (num <= 1) {
return 1;
} else {
return num + computeFactorial(num - 1);
}
}
}
二、访问权限、内部类、单例模式
访问权限
mian方法解释:由JVM调用,可以任意调用,而不需要考虑权限
public static void main(String[] args) {}
- public:公共的,访问权限修饰符;Java源码中,公共类只能有一个,且必须和源码文件名相同
- static:代表其为静态语法,跟当前类有关;去掉后main方法变成一个成员方法,而main方法需要以任意的方法调用它,不应该有任务限制
访问权限分类:(按权限范围由小至大排序)
- private:私有的,同一个类中可以使用
- default:默认权限,不设定权限时JVM默认提供权限(包权限/路径权限)
- protected:受保护的权限,子类可以访问
- public:公共的,任意使用
package chapter04;
public class Java17_Object_Access {
private String name;
public String userName;
String sex;
public static void main(String[] args) {
User17 u = new User17();
// System.out.println(u.name); 报错:'name' has private access in 'chapter04.User17
System.out.println(u.userName);
System.out.println(u.sex);
System.out.println(u.age);
}
}
class User17 {
private String name;
public String userName;
String sex;
protected int age;
void test() {
System.out.println(name);
System.out.println(userName);
System.out.println(sex);
System.out.println(age);
}
}
class Child17 extends User17 {
void test() {
System.out.println(age);
}
}
package chapter04;
public class Java03_Object {
public static void main(String[] args) {
User17 user17 = new User17();
System.out.println(user17.sex);
}
}
package chapter03;
//import chapter04.User17;
import chapter04.Java17_Object_Access;
public class Java01_FlowControl {
// User17 user = new User17(); 报错:'chapter04.User17' is not public in 'chapter04'. Cannot be accessed from outside package
Java17_Object_Access user = new Java17_Object_Access();
// System.out.println(user.name); 报错:'name' has private access in 'chapter04.Java17_Object_Access'
System.out.println(user.userName);
// System.out.println(user.sex); 报错:'chapter04.User17' is not public in 'chapter04'. Cannot be accessed from outside package
}
}
package chapter04.childpackage;
import chapter04.Java17_Object_Access;
public class TestPackage {
public static void main(String[] args) {
Java17_Object_Access user = new Java17_Object_Access();
// System.out.println(user.name); 报错:'name' has private access in 'chapter04.Java17_Object_Access'
System.out.println(user.userName);
// System.out.println(user.sex); 报错:'chapter04.User17' is not public in 'chapter04'. Cannot be accessed from outside package
// System.out.println(user.age); 报错:Cannot resolve symbol 'age'
}
}
所谓访问权限,其实就是访问属性,方法的权力和限制
理解:
- private:同类
- default:同类,同包(路径)
- protected:同类,同包,子类
- public:公共的
package chapter04;
public class Java17_Object_Access_01 {
public static void main(String[] args) {
/*
谁访问? Java17_Object_Access_01
访问谁? Person17 -> super -> (实际:java.lang.Object)
*/
person.clone();
// 报错:'clone()' has protected access in 'java.lang.Object'
}
}
class Person17 {
void test() throws Exception{
clone();
}
}
内部类
Java中不允许外部类使用private、protected修饰
外部类:在源码中直接声明的类
内部类:类中声明的类,当成外部类的属性使用即可,需要构建外部类对象才可以使用
class OuterClass {
class InnerClass {
}
}
内部类的使用
OuterClass outerClass = new OuterClass();
OuterClass.InnerClass innerClass = outerClass.new InnerClass();
单例模式
JVM默认提供的构造方法其实是公共的,无参的
public static void main(String[] args) {
// User19 user = new User19();
User19 user = User19.getInstance();
User19 user1 = User19.getInstance();
User19 user2 = User19.getInstance();
User19 user3 = User19.getInstance();
User19 user4 = User19.getInstance();
User19 user5 = User19.getInstance();
}
class User19 {
private User19() {
}
public static User19 getInstance() {
returnnew User19();
}
}
产生问题:
- 类的创建过程复杂
- 类的对象消耗资源
解决
class User19 {
private static User19 user19 = null;
private User19() {
}
public static User19 getInstance() {
if (user19 == null) {
user19 = new User19();
}
return user19;
}
}
三、final
Java中提供了一种语法,可以在数据初始化后不被修改,使用关键字:final
- final修饰的变量,变量的值初始化后无法修改
- 一般将final修饰的变量称之为常量,或不可变变量
final String name = "zhangsan"; System.out.println(name); // name = "lisi"; 报错:Cannot assign a value to final variable 'name'
- final修饰的属性,JVM无法自动初始化,需要自己手动处理,但属性值不能发生变化
class User20{ // 类中声明的属性其实就是类的变量 public final String name = "lisi"; } User20 user = new User20(); System.out.println(user.name1); // user.name1 = "wangwu"; 报错:Cannot assign a value to final variable 'name' class User20{ public final String name; public User20(String name){ this.name = name; } } User20 user = new User20("wangwu"); System.out.println(user.name);
- final可以修饰方法,但该方法不能被子类重写
class User20{ public final void test() { } } class Child20 extends User20{ public void test() {} 报错:test()' cannot override 'test()' in 'chapter04.User20'; overridden method is final }
- final可以修饰类,该类不能被继承,没有子类
final class User20{ } class Child20 extends User20 { 报错:Cannot inherit from final 'chapter04.User20' }
- final不允许修饰构造方法
- final可以修改方法的参数,一旦修饰,参数无法修改
public void test (final String name) { name = "lisi"; 报错:Cannot assign a value to final variable 'name' }
四、抽象
基础知识
分类
- 抽象类:不完整的类
abstract class 类名
- 抽象方法:只有声明,没有实现
abstract 返回的类型 方法名(参数)
在面向对象中
- 分析问题:对象(具体)=>类(抽象)
- 编写代码:类(抽象)=>对象(具体)
简易理解:抽象相当于生活中使用不同交通工具出行,无论是开汽车,乘火车还是坐飞机,使用的交通工具不同,但本质都是为了出行。
抽象类和抽象方法
抽象类无法构建对象,因为类不完整
abstract class Person21 {}
// Person21 person21 = new Person21(); 报错:'Person21' is abstract; cannot be instantiate
如果一个类中含有抽象方法,那么这个类是抽象类
如果一个类是抽象类,它的方法不一定是抽象方法
abstract class Person21 {
public void sleep() {
}
}
抽象类无法直接构建对象,可以通过子类间接构建对象
abstract class Person21 {
}
class Chinese21 extends Person21 {
}
public static void main(String[] args) {
Chinese21 chinese21 = new Chinese21();
}
如果抽象类中含有抽象方法,那么子类继承抽象类时需要重写抽象方法,将方法补充完整
abstract class Person21 {
public abstract void eat();
public void sleep() {
}
}
class Chinese21 extends Person21 {
public void eat(){
System.out.println("开始吃饭");
}
}
public static void main(String[] args) {
Chinese21 chinese21 = new Chinese21();
chinese21.eat();
}
abstract不能与final、class同时使用
abstract class Person21 {
// final abstract class Person21 { 报错:Illegal combination of modifiers: 'final' and 'abstract
public abstract void eat();
// public final abstract void eat(); 报错:Illegal combination of modifiers: 'final' and 'abstract
public void sleep() {
}
}
五、接口
可以简单理解为规则
基本语法
interface 接口名称 {规则属性,规则行为}
- 接口其实是抽象的
- 规则属性必须为固定值不能修改
- 属性和行为必须为公共的
- 属性应该是静态的;行为应该是抽象的
- 接口和类是两个层面得东西; 接口可以继承其他接口
- 类得对象需要遵循接口,在java中,这个遵循称之为实现;类需要实现接口,而且可以实现多个接口
举例:通过USB接口提供能源
- 定义USB接口
interface USBInerface {}
- 定义USB提供能源的接口,需要继承USB接口
interface USBSupply extends USBInerface{ public void powerSupply(); }
- 定义USB接收能源的接口,也需要继承USB接口
interface USBReceive extends USBInerface{ public void powerReceive(); }
- 定义接收USB提供能源的类,继承USB提供能源的接口,同时重写提供能源的方法
class Computer implements USBSupply{ public USBReceive usb1; public USBReceive usb2; public void powerSupply() { System.out.println("电脑提供能源"); usb1.powerReceive(); usb2.powerReceive(); } }
- 定义接收能源后亮灯的类,继承USB接收能源的接口,同时重写接收能源的方法
class Light implements USBReceive{ public void powerReceive() { System.out.println("电灯接收能源"); } }
- 实现提供能源和接收能源
public static void main(String[] args) { Computer computer = new Computer(); Light light1 = new Light(); computer.usb1 = light1; Light light2 = new Light(); computer.usb2 = light2; computer.powerSupply(); }