1 .什么是构造方法?
- 什么是构造方法?
- 1)方法名和类名一致
- 2)没有具体返回值类型
- 3)连void都没有
- 构造方法是支持方法重载(方法名相同,参数列表不同,与返回无关)
- public 方法名和类名一致(要么空参/要么带上形式参数列表){}
class Student{
//无参构造方法
public Student(){
System.out.println("这是Student的无参构造方法");
}
//有参构造方法:带上参数类型以及参数名
public Student(String name){
System.out.println(name);
System.out.println("这是带一个参数的有参构造方法");
}
public Student(String name,int age){
System.out.println(name+"---"+age);
System.out.println("这是带两个参数的有参构造方法");
}
}
- 使用构造方法的注意事项:
-
1)一个类中如果没有提供任何构造方法,系统会默认提供一个无参构造方法
-
2)如果一个类中提供了有参构造方法,系统不会无参构造方法,如果你还要使用无参构造方法来创建类对象,报错!
-
类名 对象名 = new 类名() ; 默认执行的无参构造方法
-
给成员变量赋值就两种方式:
-
1)setXXX(xx)赋值!
-
2)有参构造方法赋值!
2.一个类中的成员 (使用有参构造方法也可以完成成员变量的赋值)
一个标准类 :
成员变量:属性私有化
成员方法:setXXX(xx)/ getXXX()
构造方法: 无参构造方法永远给出来的!
有参构造方法(开发中,视情况而定)
3. 成员变量(什么时候将变量定义为成员变量)
class Demo{
// int a ;
//int b ;
// public int add(){
// return a + b ;
// }
public int add(int a,int b){
return a +b;
}
}
// 变量的定义的时候:如果能够描述这个事物的属性---定义成员变量
//长方形----长和宽:就是它的属性
4. static关键字
本身的含义"共享/共用"
被static修饰符的变量以及方法-----> "类成员"
随着类的加载而加载
5.代码块 ---- {} (重点去掌握:代码块的优先级,静态代码块,构造代码块,构造方法)
```java
静态代码块:类就加载一次,所以static代码块也就执行一次!
static{} (实际开发中,这个使用居多)
构造代码块 {} (在类的成员位置) :如果类中有这个,先执行构造代码块,在执行构造方法
局部代码块:限定变量生命周期的
一个类中如果有静态代码块,有构造代码块,有构造方法
静态代码块 > 构造代码块 > 构造方法
继承 (extends)
什么是继承?
将多个事物(类)的共性内容抽取到一个独立的事物(类)中,
- 这个事物(类)和其他事物(其他类)之前产生一种关系,称为"继承" 关键字 “extends”
格式:
class 父类名{
共性内容:属性私有化
对外提供公共的访问方法
//其他成员方法
}
class 子类名 extends 父类名{
}
继承的好处?
1)提高了代码的复用性
* 2)提高了代码的维护性(方便后期维护)
* 3)类与类产生的继承关系,是多态的前提条件!
*
继承的弊端?
* 继承让类与类之间产生了关系,类的耦合性增强了,当父类发生变化是子类实现也不得不跟着变化, 削弱了子类的独立性
继承的里面的注意事项
1)类和类之间的关系,只支持"单继承"
*
* class Fu{}
* class GrandFu{}
* class Zi extends Fu,GrandFu{}//错误的! (多继承,Java没有多继承的概念)
*
* 2)不支持多继承,但是可以 "多层继承"
*
11_8今日内容
1.继承的注意事项(重点)
1)子类继承父类,继承父类的非私有的成员,私有的成员,可以间接访问!
2)子类继承父类,构造方法是不能继承的,通过一个关键字来访问 super() (在继承 super的使用)
2. 继承的成员变量访问问题(重点)
1)如果子类继承父类,子类的成员变量名称和父类的成员变量不一致,分别访问即可
2)如果子类中的成员变量名称和父类的成员变量一致,如何访问呢?
就近原则机制
* 1)首先先在子类的局部位置(成员方法)找,如果有,就使用
* 2)如果子类的局部位置没有,那么就在子类的成员位置中找,有就使用
* 3)如果子类的成员位置也没有,那么就在父类的成员位置中找,有就使用,
* 4)如果父类也没有,继续往他的父类上找,最终顶层父类中都没有,那么报错(找不到这个变量!)
3.继承的构造方法访问问题 :super来访问(重点)
1)子类继承父类,子类的所有构造方法的默认第一句话都super() ;(可以省略的不写) 访问父类的无参构造方法
2)如果父类中没有给出无参构造方法, 那么会出现什么情况?如何解决?
4.继承的成员方法访问问题
子类继承父类, 如果子类和父类的成员方法名称不一致,分别调用即可
如果如果一致,而且一模一样,方法重写Override (方法覆盖/方法复写),重写的时候必须要保证它的访问权限足够大!
class Fu{
public void show(){}
}
class Zi extends Fu{
void show(){ //不行,访问权限问题:要么跟父类的一模一样,要么永远带上public
}
}
5.继承的中相关的面试题
继承关系中, 父类的中如果没有无参构造方法(存在有参构造方法),子类会出现什么情况?如何解决呢?
*
* 子类全部报错,子类的所有构造方法都默认访问父类的无参构造方法(子类的所有构造方法的第一句话super();,可以省略不写)
*
* 1)解决方案1:永远给出类的无参构造方法
* 2)如果现在不给出父类无参构造方法,如何解决呢?
* 让子类的所有构造方法显示的访问父类的有参构造方法!(只要父类出现初始化 :执行构造方法就是初始化)
*
* 3)子类的所有构造方法中的某一个只要能够让父类初始化即可!
*
* 创建Zi zi = new Zi() ; 在执行Zi类的无参构造方法的时候
* 让它先执行子类的有参构造方法 this(xx) ;
* 让后在子的有参构造方法中,让它先让父类初始化 super(xx) ; 访问父类的有参构造方法
6.引入概念—多态(重点)
多态的概念
能够体现事物的不同形态(程序中,内存的变化!)
多态的前提条件:
1)必须有继承关系 (如果没有继承,不谈多态)
* 2)必须存在方法重写
* 猫和狗都需要吃饭,吃的东西不一样(具体的动物类中应该给出具体体现)
* 3) 必须存在父类引用指向子类对象
* 格式:
* 父类名 对象名 = new 子类名() ; (向上转型!)
多态的好处
1)可以提高代码的扩展性 (父类引用指向子类对象 Fu fu = new Zi()) 多态保证的 (重点)
* 2)可以提高代码的复用性以及维护性(由继承保证的)
多态的弊端
父类引用指向子类对象, 父类名 对象名 = new 子类名() ;(向上转型)这种格式无法访问子类的特有功能
* 解决方案:
* 1)直接创建子类对象 子类名 对象名 = new 子类名() ;
* 虽然可以,但是new 子类名() ;需要开辟堆内存空间(消耗内存空间) (内存角度考虑不太好)
* 2) 推荐:向下转型
* 将父类引用强转为子类引用!-----就是我们 基础"强转类型转换" (将大类型---小类型)
* int num = 65 ;
* char c = (char)num ; // 'A'
* 父类名 父类的引用 = new 子类名() ; 向上转型
* Fu f = new Zi() ;
* 子类名 对象名 = (子类名)父类的引用; 向下转型 --前提必须有向上转型
* Zi z = (Zi)f;
7.什么是方法重写?
Override,在继承关系中,子类出现了一摸一样的方法声明(权限修饰符,返回值类型,方法名,参数列表都相同),子类将父类的方法覆盖了,实现自己的业务逻辑...
8.final关键字的特点
final修饰类,该类不能继承
final修饰变量,此时变量是一个常量(自定义常量)
编译时期常量:(jvm不需要加载) public static final 基本数据类型 变量名 = 值;
运行时期常量:(jvm需要加载) public static final 引用数据类型 变量名 = new xxx();
final修饰成员方法,该方法不能被重写
9.this和super的区别
1)概念的区别
this:代表的当前类对象的地址值引用
super:代表的父类的空间表示(父类对象的地址值引用)
2)使用不同
2.1)针对成员变量访问
this.变量名 ; 访问的本类的成员变量
super.变量名; 访问的父类成员变量
2.1)访问构造方法
this() ; 访问本类的无参构造方法
this(xx); 访问本类的有参构造方法
super() ;访问父类的无参构造方法
super(xx);访问父类的有参构造方法
2.2)访问成员方法
this.方法名() ;访问本类的成员方法
super.方法名() ;访问父类的成员方法
11_9今日内容
1. 多态的弊端—使用向下转型解决,可能存在一个问题
如果向下转型(将父类引用强转为子类引用),使用不当(),会导致程序出现异常 "ClassCastException" 类转换异常
Animal a = new Dog() ;//堆内存是狗 (狗是动物)
Dog d = (Dog)a;//还原成狗
a = new Cat() ;
Dog dd = (Dog)a; 编译不报错 ,运行时候报错!
2.abstract关键字 (抽象)
么是抽象类?
* 一个事物的某个行为应该具体的事物的具体体现,将这个事物顶层次(父类)可以定义"抽象"
* 举例
*
* 动物事物---都具备吃和睡的行为
* 只有见到具体的事物才具备的具体行为 "猫","狗"吃和睡不一样,应该在具体事物中给出具体的体系,那么在
* 动物事物中,仅仅一个声明!(没有方法体)
* 抽象类的定义:
* abstract class 类名{}
* 有抽象方法的类一定是抽象类, 抽象类不一定都是抽象方法 (重点)
*
* 抽象方法的格式:
* 权限修饰符 abstract 返回值类型 方法名(空参/无参);
*抽象类的特点:
* 1)抽象类不能进行实例化! (不能 创建对象)
* 2)抽象类的子类如果也是抽象类,不能实例化,一定会提供最具体的子类 完成实例化(创建对象)
* 抽象的父类名 对象名 = new 具体的子类名() ; 抽象类多态
抽象类的成员特点:
* 成员变量:
* 既可以是变量,也可以是常量!(加入final修饰)
* 成员方法:
* 皆可以存在抽象方法(不能省略abstract关键字,必须强转子类重写),也可以定义非抽象方法
* 构造方法:
* 无参构造/有参构造都可以存在, 构造方法都需要让父类先初始化,然后再是子类进行初始化!
3.abstract在使用它和哪些关键字冲突?
-
不能private一块用:被private修饰的成员需要在当前类进行访问,而如果加入abstract,强制子类完成...
-
不能和final一块用: 被final修饰的成员方法,不能被重写!而abstract抽象方法,必须强制子类重写
-
不能和static一块用:被static修饰的成员方法,算不上重写..
4.接口(接口:是比抽象类还抽象的一种概念)
什么是接口?
* 接口 体现的是这个事物本身不具备的功能,额外的功能;
*
* 举例:
* 猫和狗 ----> 开始不具备 "跳高","钻火圈"
* --->驯养师---->训练猫和狗---->后天具备 "跳高","钻火圈"
*
* 中国人---->经过后天学习 "英语口语" ----> 具备说"英语口语"的行为!
*
接口有什么特点
* 1)接口的方法不能有方法体,只能是抽象方法 而且隐藏public abstract(可以省略不写)
* 2)接口不能实例化(不能创建对象)
*
* 3)如果接口的实现类它是一个抽象类(不能实例化),肯定有一个具体的接口的实现类来进行new对象
* 接口名 对象名 = new 具体的子实现类() ; 接口多态
* 要实现接口里面的额外功能---->才具备这功能
* 开发中定义接口的实现类(子类)名
* class 接口名+Impl implements(实现) 接口名{
*
*
* }
* 接口的成员特点:
* 成员变量: 只能是常量--- 存在默认修饰符 public static final (可以省略)
* 成员方法: 只能是抽象方法----存在默认修饰符 public abstract(可以省略)
* 构造方法: 接口没有构造方法!
接口和抽象类的区别?
抽象类:
成员变量:既可以是常量,也可以变量
成员方法:既可以是抽象方法,也可以是非抽象方法
构造方法:无参/有参构造都存在,子类父类继承,需要分层初始化
接口
成员变量:只能是常量 public static final(默认修饰符)
成员方法:只能是抽象方法 public abstract(默认修饰符)
构造方法:没有---需要借助子实现类进行实例化(创建对象)
2)关系的区别
类与类:可能是一些抽象类, 继承关系,只支持单继承,不支持多继承,但是可以多层继承
abstract class Animal{}
abstract class Cat extends Animal{}
class XXCat extends Cat{}
类与接口:实现关系 implements
一个类继承另一个类(可能也是抽象类)的同时,还可以实现多个接口
接口与接口:继承关系 extends
支持单继承,可以多继承,多层继承!
3)设计理念的区别
抽象类--不能实例化
需要通过具体的子类实现类(继承关系)
核心设计理念体现都是一种"is a"的关系(xxx是XX的一种)
接口---不能实例化
需要通过具体的子实现类进行实例化(实现关系implements)
核心设计理念体现的是 事物的一种额外功能
5.权限修饰符的范围
默认修饰符
私有修饰符private
受保护的 protected
公共的public (权限最大)
11_10今日总结
1. 关于类与类,类与接口,接口与接口的关系!
(1)类与类:继承关系,单继承,可以多层继承。
(2)类与接口:实现关系,非抽象类实现接口时,必须将接口中的方法实现。抽象类实现接口时,可以实现也可以不实现方法。
(3)接口与接口:继承关系,一个接口可以继承多个接口。
`
2.形式参数问题和返回值问题----->只研究引用类型
形式参数问题
情况1 具体类
package com.qf.args_02;
/**
* @author 高圆圆
* @date 2022/11/10 10:32
* 方法形式参数如果引用类型
* 数组---->需要传递数组对象
* 类
* 具体类----->实际参数,需要传递当前类对象
* 抽象类
* 接口
*/
//学生类
class Student{
public void studyJavaEE(){
System.out.println("学生正在学习JavaEE");
}
}
//定义一个类
class StudentDemo{
public void method(Student student){//形式参数引用类型:具体类 ---->实际参数需要该Student类的具体对象
student.studyJavaEE(); //具体的对象(空间地址值)调用成员方法
}
}
//测试类
public class ArgsDemo {
public static void main(String[] args) {
//需要调用StudentDemo类中method方法
//1)需要创建StudentDemo类对象
StudentDemo sd = new StudentDemo() ;
//2)调用方法
Student s = new Student() ;
sd.method(s);
System.out.println("----------------------------------------");
//可以都匿名对象
new StudentDemo().method(new Student());
}
}
情况2 抽象类
package com.qf.args_02;
/**
*方法形式参数如果引用类型
* 数组---->需要传递数组对象
* 类
* 具体类----->实际参数,需要传递当前类对象
* 抽象类---->抽象类不能实例化,实际参数传递该抽象类的子类对象 (抽象类多态)
* 接口
*
*/
//抽象的人类
abstract class Person{
public void work(){
System.out.println("人都需要工作");
}
}
//定义一个PersonDemo类
class PersonDemo{
public void show(Person p){//形式参数一个引用类型:抽象类--->实际参数,需要传递抽象类的子类对象!(抽象类多态)
p.work() ;
}
}
//定义一个抽象类的子类(具体类,否则还不能实例化)
//工人类
class Worker extends Person{
@Override
public void work() {
System.out.println("爱敲代码,爱生活,爱高圆圆!");
}
}
//测试类
public class ArgsDemo2 {
public static void main(String[] args) {
//调用PersonDemo类的show方法
//1)创建PersonDemo类对象
PersonDemo pd = new PersonDemo() ;
//2)调用方法
//Person p = new Person() ; //抽象类不能实例化(不能创建对象)
// pd.show(p);
//抽象类多态
Person person = new Worker() ;
pd.show(person);
System.out.println("------------------------");
//匿名对象
new PersonDemo().show(new Worker());
}
}
情况3 接口
package com.qf.args_02;
/**
*方法形式参数如果引用类型
* 数组---->需要传递数组对象
* 类
* 具体类----->实际参数,需要传递当前类对象
* 抽象类---->抽象类不能实例化,实际参数传递该抽象类的子类对象 (抽象类多态)
* 接口 ----->接口不能实例化,实际参数需要传递该接口的子实现类对象(接口多态)
*
*
*/
//定义一个接口
interface Mary{
//结婚
public abstract void mary() ;
}
//定义MaryDemo类
class MaryDemo{
public void function(Mary mary){//形式参数是引用类型,接口类型---实际参数?需要接口的子实现类对象(接口多态)
mary.mary();
}
}
//需要的接口的子实现类
class You implements Mary{
@Override
public void mary() {
System.out.println("结婚了,很开心...");
}
}
//测试类
public class ArgsDemo3 {
public static void main(String[] args) {
//需要调用MaryDemo类中function方法
//1)创建MaryDemo类对象
MaryDemo md = new MaryDemo() ;
//2)调用方法
/* Mary mary = new Mary(); //接口也是抽象的,不能实例化
md.function(mary);*/
Mary mary = new You() ; //接口多态
md.function(mary) ;
System.out.println("----------------------------------") ;
//匿名对象
new MaryDemo().function(new You());
}
}
返回值问题
情况1 具体类
package com.qf.return_05;
/**
* @author 高圆圆
* @date 2022/11/10 11:37
* 方法的返回值问题:
* 1)返回基本类型: 需要什么基本数据类型,使用对应性的类型接收
* 2)研究引用类型:
* 类
* 具体类: 需要返回的是当前具体类的对象 !
* 抽象类:
* 接口
*/
//学生类
class Student{
public void sutdy(){
System.out.println("正在学习JavaSE之面向对象");
}
}
//定义一个StudentDemo类
class StudentDemo{
/* public int add(int a,int b){
return a+b ;
}*/
public Student getStudent(){
//?
//如何返回?
//如果方法的返回值是一个引用类型:具体类,需要返回当前类的对象!
//Student s = new Student() ;
// return s ;
return new Student(); //匿名对象
}
}
//测试类
public class ReturnDemo {
public static void main(String[] args) {
//调用StudentDemo类中的getStuent方法
//1)创建对象
StudentDemo sd = new StudentDemo() ;
//2)调用方法
Student student = sd.getStudent(); //sd.getStudent() 逻辑---创建一个学生
//本质就是Student student = new Student() ;
student.sutdy();
System.out.println("-----------------------------------------") ;
//匿名对象
//链式编程(自己玩)
new StudentDemo().getStudent().sutdy();
}
}
情况2 抽象类
package com.qf.return_05;
/**
* @author 高圆圆
* @date 2022/11/10 11:37
* 方法的返回值问题:
* 1)返回基本类型: 需要什么基本数据类型,使用对应性的类型接收
* 2)研究引用类型:
* 类
* 具体类: 需要返回的是当前具体类的对象 !
* 抽象类: 需要返回的是当前抽象类的子类对象(抽象类多态)
* 接口
*/
//抽象类
abstract class Person{
public void work(){
System.out.println("人都需要工作");
}
}
//定义一个PersonDemo
class PersonDemo{
public Person getPerson(){
// Person p = new Person() ;
//return p;
//return new Person() ;
//抽象类不能new,可以通过抽象类的子类进行实例化
//抽象类多态
// Person p = new Programmer() ;
// return p;
return new Programmer() ;
}
}
//定义出现抽象类的子类
class Programmer extends Person{
@Override
public void work() {
System.out.println("程序员日日夜夜coding...");
}
}
//测试类
public class ReturnDemo2 {
public static void main(String[] args) {
//调用PersonDemo的getPerson()
PersonDemo pd = new PersonDemo() ;
Person person = pd.getPerson();//方法的本质---Person person = new Programmer() ;
person.work() ;
System.out.println("----------------------------") ;
//匿名对象
new PersonDemo().getPerson().work();
}
}
情况3 接口
package com.qf.return_05;
/**
* @author 高圆圆
* @date 2022/11/10 11:37
* 方法的返回值问题:
* 1)返回基本类型: 需要什么基本数据类型,使用对应性的类型接收
* 2)研究引用类型:
* 类
* 具体类: 需要返回的是当前具体类的对象 !
* 抽象类: 需要返回的是当前抽象类的子类对象(抽象类多态)
* 接口 :需要返回的是接口的子实现类对象(接口多态)
*/
//定义一个接口
interface Love{
void love() ;
}
//有一个类LoveDemo
class LoveDemo{
//成员方法
public Love getInstance(){ //返回值是接口类型
// Love love = new Love() ; //接口不能实例化
//return love;
//方式1:
//接口多态:需要接口类型---返回接口的子实现类对象
// Love love = new LoveImpl() ;
//return love ;
//方式2:匿名对象
return new LoveImpl() ;
}
}
//需要有一个子实现类来实现接口
class LoveImpl implements Love{
@Override
public void love() {
System.out.println("爱生活,爱Java");
}
}
//测试类
public class ReturnDemo3 {
public static void main(String[] args) {
//调用LoveDemo里面的getInstance()方法
LoveDemo ld = new LoveDemo() ;
Love love = ld.getInstance(); //方法本质 --Love love = new LoveImpl() ;
love.love();
System.out.println("------------------------------------------") ;
//匿名对象
new LoveDemo().getInstance().love();
}
}
3.包package的含义
ackage包—本质就是文件夹(目录)
-
程序员在编写代码存储的地址
-
包---->开发中 (公司域名反写,多个包中间.隔开)
-
公司域名
-
com.qf
-
本质
-
com文件夹
-
qf文件夹
-
xx.java
- 包----为了维护代码结构的(代码分层)
-
com.qf.pojo/domain/entity: 存放Java实体类(满足JavaBean规范:)
-
1)这个类是具体类
-
2)属性私有化 (属性必须全部字母小写)
-
3)对外提供公共的setXXX(xx)/getXXX()
-
class Prodcut{
-
private int id ;//商品id
-
private String pname ; //商品名称
-
private int pprice ; //商品价格
-
private String pdesc ; //商品描述
-
private String pic ; //图片地址
-
//setXXX(XX)/getXXX()
-
}
-
com.qf.service: 业务访问层
-
interface ProductSevice{} 业务接口
-
com.qf.service.impl: 业务实现
-
class PrductServiceImpl implements ProductService{
-
//以后---->调用dao层代码--->获取数据
-
//完成if...else...逻辑判断
-
}
-
com.qf.dao (DAO---Data Access Object :数据访问对象) 数据库访问层(持久层)
-
interface ProductDao{ //xxxDao
-
void add(Product product) ;
-
void delete(int id) ;
-
void update(Product product);
-
}
-
com.qf.dao.impl
-
class ProductDaoImpl implements ProductDao{
-
//JDBC--->java代码连接数据库
-
}
-
com.qf.commons/utils:存储一些通用工具类
-
com.qf.controller: 前后端交互的代码(前端和后端的中间层:连接层)
-
com.qf.api: ---->接口文档工具
-
jdk提供----java.swing/awt:图形界面化GUI编程 (早期)
4.权限修饰符的默认修饰符/private/protected/public
私有修饰符priate: 在同一个包下的同一个类中(范围最小)
默认修饰符: 在同一个包下的同一个类中 同一个包下的子类中/同一个包下的无关类中
受保护的protected:在同一个包下的同一个类中 同一个包下的子类中/同一个包下的无关类中 / 在不同包的子类中
公共的public:都可以,访问权限最大!
一个包下:只能有一个公共类
public class Test1{
public static void main(String[] args){
}
}
5.内部类(了解)
//内部类----实际开发中(应用层面居多)
//内部类里面的一些访问方式(重点)
//属于设计层面(jdk源码里面会看到)
class Outer{
//成员内部类
class Inner{
}
}
class Outer{
public void show(){
//局部位置
class Inner{} //局部内部类
}
}
6.常用类
重要的几个类(凡是 类型转换都是重点)
Object
String (里面功能最多
转换
截取
替换
字典比较
)
StringBuffer(线程安全的类)
java.util.Date:日期类
String日期文本---->Date日期格式
基本类型四类八种---->八个引用类型(Inetger,Character)
BigDecimal:小数精确计算
System
11_11今日总结
1. 局部内部类
- 局部内部类:
-
1)也可以访问外部类的成员包括私有
-
jdk7以前(包括jdk7):局部内部类访问局部变量的时候,局部变量必须使用final进行修饰!,为什么?
-
局部变量它随着方法调用而存在,随着方法调用结束而消失,但是现在是通过局部对象调用它的成员方法还在使用这个局部变量
-
局部变量必须为常量(加入final)---局部内部类对象不会立即消失,等待gc回收!
-
jdk8以及jdk8以后 jvm已经对这个局部变量优化 ,将final已经省略了!
//特点和成员内部类一样,局部内部类也可以直接外部类的包括私有!
class Outer{
public void method(){
class Inner{
public void show(){
//局部变量
int num = 20 ;//jdk7(jdk7以前):此时num必须显示的加入final
//jdk8--final省略了,但是是存在!(必须为常量)
}
}
//创建Inner类对象,调用show()方法
Inner in = new Inner();
in.show() ;
}
}
//面试题:局部内部类访 访问它的成员方法里面的局部变量,局部变量有什么特点?
2.内部类的面试题— 看程序,写结果
外部类和内部类:没有继承关系
- 看程序,补全代码
- 分别在控制台输出30,20,10
//外部类
class Outer2{
int num = 10 ;
//成员内部类
class Inner2{
int num = 20 ;
public void show(){
int num = 30 ;
//补全代码
System.out.println(num) ;
System.out.println(this.num); //访问自己本类的成员变量
//方式1
//System.out.println(new Outer2().num) ;
//方式2:外部类的this限定
System.out.println(Outer2.this.num);
}
}
}
//测试类
public class InnerClassTest {
public static void main(String[] args) {
Outer2.Inner2 oi = new Outer2().new Inner2() ;
oi.show();
}
}
3.匿名内部类 (重点)
- 匿名内部类: 没有名字的类
- 应用范围: 在局部位置中的(方法定义中或者声明上)
- 匿名内部类的格式:
-
new 类名或者一个接口名(){
-
重写方法(){
-
...
-
}
-
}
- 匿名内部类的本质:就是继承该类(抽象类)或者是实现类了该接口的子类对象!
*/
//定义一个接口
interface Love{
void show() ;
void show2() ;
}
//外部类
class Outer{
//外部类的成员方法
public void method(){
//使用匿名内部类的格式将Love接口里面的show方法实现了
/* class LoveImpl implements Love{
@Override
public void show() {
System.out.println("show Love");
}
}
//接口多态
Love love = new LoveImpl() ;
love.show();*/
/*
new 类名或者一个接口名(){
重写方法(){
...
}
};
*/
//直接使用匿名内部类
/* new Love(){
//重写接口的方法
@Override
public void show() {
System.out.println("show Love...");
}
@Override
public void show2() {
System.out.println("show2 Love...");
}
}.show();
new Love(){
//重写接口的方法
@Override
public void show() {
System.out.println("show Love...");
}
@Override
public void show2() {
System.out.println("show2 Love...");
}
}.show2();*/
//当接口中或者抽象类中有多个抽象方法的时候,匿名内部类使用比较麻烦,通过下面这种简化访问代码量
//可以给 new 类名或者接口名(){.重写方法..} 起一个名字(对象名),使用这个对象名可以访问
Love love = new Love(){
@Override
public void show() {
System.out.println("show Love");
}
@Override
public void show2() {
System.out.println("show2 Love");
}
};
love.show();
love.show2();
}
}
//测试类
public class InnerClassDemo {
public static void main(String[] args) {
//创建外部类对象
Outer outer = new Outer() ;
outer.method();
}
}
4.常用类(掌握jdk提供的常用类的常用功能)
java.lang.Object—>所有的类父类(jdk提供的类/我们自定义的类)
equals():建议所有子类必须重写---->不重写,引用类型比较就是地址值是否相等
底层原码用的就是 ==
toString():建议所有的子类必须重写这个方法
getClass():---获取一个类的字节码文件对象 ---- >Class(jdk提供的:class对象:字节码文件对象)
clone():克隆
和线程(锁)相关的功能:
wait():线程等待
notify():线程唤醒
java.util.Scanner:键盘录入—>提供一些判断功能 hasNextXXX()
如果录入的是int—>但是接收的String line = 键盘录入对象.nextLine();
java.lang.String(开发中经常用到的)
需求:将一个数组—遍历----转换成String (必须使用String 的拼接)
拼接:
String s = “” ;
转换功能
获取功能
拼接功能:concat(String str)
分割/拆分
截取
按照字典顺序比较
需求:
键录入一个字符串
输入"Helloworld"
输出 "hELLOWORLD"
输入 "mbabm"
输出 :判断这个字符串是否为对称字符串? true/false
java.lang.StringBuffer
Integer
Character
System
Arrays:数组工具类(方便使用)
5.选择排序
使用数组0角标对应的元素依次和后面的元素比较,小的往前放,第一次比较完毕,最小出现在最小索引处!
public class ArrayTest {
public static void main(String[] args) {
//提供一个数组,静态初始化
int[] arr = {24,69,87,56,13} ;
System.out.println("排序前:") ;
String str = printArray(arr) ;
System.out.println(str) ;
System.out.println("------------------------------------") ;
System.out.println(printArray(arr)) ;
int[] arr2 = selectSort(arr);
//System.out.println(arr2);
System.out.println(Arrays.toString(arr2));//Arrays数组工具类toString--->将数组转换成String
}
//定义一个选择排序的方法
public static int[] selectSort(int[] arr){
for(int x = 0 ; x < arr.length - 1;x++){//比较的次数
for(int y = x+1; y < arr.length;y++){ //元素进行判断 比较
//如果前面的元素比较后面元素大,将后面的元素往前放
if(arr[x] > arr[y]){
int temp = arr[x] ;
arr[x] = arr[y] ;
arr[y] = temp ;
}
}
}
return arr;
}
//遍历数组 --->没有返回值类型void--->直接输出
public static String printArray(int[] arr){
//定义一个字符串
String s = "" ; //结果变量
s+= "[" ;
//遍历数组
for(int x = 0 ; x < arr.length ; x++){
if(x==arr.length-1){
//取到最大索引值,对应最后一个元素
s+=arr[x] ;
s+="]" ;
}else{
//中间角标对应的元素
s+= arr[x] ;
s+=", ";
}
}
return s;
}
}