第三周总结
day12
1.private关键字的特点
1)被private修饰的变量/或者方法,只能在本类中访问,外界类不能直接访问;
2)private修饰的成员变量以及成员方法,不能直接访问,但是可以通过公共的访问间接访问
3)private权限修饰符的范围最小:只能在本类访问
class Demo{
private int num = 20 ;
private void method(){
Sysetem.out.println("method Demo...");
}
//公共的访问方法
public void show(){
System.out.println( num) ; //20
method() ; //调用私有方法// method Demo...
}
}
class MyMain{
public static void main(String[] args){
//要访问Demo列中的show方法()
//创建Demo类 对象 类名 对象名= new 类名() ;
Demo d = new Demo() ;
d.show() ;
}
}
2.封装
一个类类中的成员变量(描述事物的属性)需要对外隐藏,被private修饰,为了保证数据安全性;对外需要提供公共的访问方法setXXX()赋值/ getXXX() 获取值 ;
3.冒泡排序的思想以及核心代码体现
冒泡排序的思想:
两两比较,较大的往后放,第一次比较完毕,最大值出现在最大索引处 ;
依次比较,可以得到排好序的数组
规律:
1)两两比较: 大的往后放,
2)第一次比较, 有0不比
第二次比较,有1个不比
....
比较次数:数组长度-1次
for(int x = 0 ; x <arr.length-1; x++){ // 比较次数
for(int y = 0 ; y < arr.length-1-x ; y ++){
//两两比较: 大的往后放,
if(arr[y]>arr[y+1]){
//中间变量
int temp = arr[y] ;
arr[y] = arr[y+1] ;
arr[y+1] = temp ;]
}
}
}
4.面向对象的思想特点
1)解决实际问题上,更符合生活中的思想行为习惯
2)让复杂的事情简单化
3)我们从执行者 变成指挥者
5.如何描述一个手机事物,有品牌,价 格,颜色的属性以及可以打电话的行 为?
class Phone{
//属性私有化
private String brand ; //品牌
private int price ; //价格
private String color ; //颜色
//对外提供公共访问方法 setXXX()/getXXX()
//赋值
public void setBrand(String b){ //brand
brand = b ; //brand = brand
}
public void setPrice(int p){
price = p ;
}
public void setColor(String c){
color = c ;
}
//获取值
public String getBrand(){
return brand ;
}
public int getPrice(){
return price ;
}
public String getColor(){
return color ;
}
//打电话
public void callPhone(){
System.out.println("手机可以打电话...");
}
}
6.匿名对象
匿名对象:就是没有名字的对象
标准的写法:
类名 对象名 = new 类名();
匿名对象的格式
new 类名(); 直接在堆内存开辟空间,使用完毕就要被回收,可以节省内
存;
格式:new 类名() ;
好处:
1)匿名对象可以作为参数传递 :可以把上面那个代码改进
2)匿名对象可以节省内存空间,因为压根没有栈内存空间,不需要开辟,直接开辟堆内存空间
3)匿名对象一般适用于一次即可,使用完毕,直接被jvm的GC(垃圾回收器)的回收;
7.方法的形式参数如果是类(引用类 型),那么实际参数如何传递?
如果方法的形式参数是类,实际参数传递,需要传递是当前类的具体类对象(以后经常会用到,可能是出题者提供的类或者jdk提供的类)
class StudentTest{
public static void main(String[] args){
//补全代码: 需求:访问StudentDemo类的method方法
//创建StudentDemo类对象
//有名字对象
StudentDemo sd = new StudentDemo() ;
//new 一个具体的学生
Student s = new Student() ;
sd.method(s) ;//实际参数
}
}
class Student{
public void study(){
System.out.println("Good good stduy ,Day day up!!!") ;
}
}
class StudentDemo{
public void method(Stduent s){ //形式参数:引用类型:Student类型
s.study() ;
}
}
8.this关键字的概念以及目的
this:代表当前类对象的地址值引用 Student s = new Student() ; s---->空间地址值的引用;
this的出现:为了防止局部变量隐藏了成员变量,
构造方法
public Phne(String brand ,int price){
this.brand = brand ;
thi.price = price ;
}
setxxx()
public void setBrand(String brand){
this.brand = brand ;
}
this的用法:
this.变量名; 变量名:访问本类的成员变量名
this.方法名() ; 访问的本类的成员方法
this()----- 访问本科无参构造方法...
this(xxx) 访问本类的有参构造方法...
9.构造方法的特点以及注意事项
构造方法特点:
1)方法名和类名相同,
2)没有具体返回值类型,
3)连void都没有
public 方法名和类名相同(){
}
构造方法的目的:就是为给类的成员初始化
Phone p = new Phone();//无参构造方法
1)栈内存开辟空间
2)堆内存申请空间
3)进行系统默认初始化,为成员变量
4)setXXX("xxx") /有参构造方法:显示初始化..
构造方法的注意事项:
1)当在书写一个标准类的时候,没有给出任何构造方法.系统会默认提供无参构造方法
2)如果提供了一个类的有参构造方法,系统就不会构造方法,所以,建议永远给出无参构造方法;
3)构造方法是可以重载的;
创建对象,就是创建实例
class Phone{
private String brand ; //null
private int age ; //0
//...SetXXX()/getXXX()...
public Phone(){} /无参构造方法
public Phone(String brand,int price){//有参构造方法
}
}
10.一个类成员的组成以及一个类 的标准写法
一个类的组成
1)成员变量
2)构造方法
3)成员方法:
一个类的标准类的写法:
1)成员变量私有化
2)无参永远给出的,有参构造根据题意要求(没有明确,全部提供)
3)成员方法,根据题意要求(没有明确是否带参,是否有返回值,直接输出语句)
day13
1.代码块
代码块: 使用{}括起来的内容
分类:
局部代码块,就是在方法定义中使用{}
{},作用:就是限定局部变量的生命周期;
构造代码块:---在类的成员位置定义的{},它有特点:在执行构造方法之前,如果类中有构造代码块,
优先执行构造代码块,作用:也可以给类的成员的数据进行初始化; (实际开发很少见到构造代码块)
只要执行构造方法,如果存在构代码块,它必须优先执行,然后才是构造方法...
静态代码块:
类就加载一次,静态代码块也就执行一次!
格式
static{ --->跟静态相关的都和类有关系,随着类的加载而加载;
里面书写代码
}
静态代码块,构造方法,构造代码块
优先级:静态代码块 > 构造代码块> 构造方法,而且每次执行构造方法之前,优先执行所有的构造构造代码块
package com.qf.code_09;
//定义一个Code类
class Code{
//静态代码块
static{
int x = 1000 ;
System.out.println(x );
}
//无参构造方法
public Code(){
System.out.println("code...");
}
//构造代码块:类的成员位置
{
int x = 100 ;
System.out.println(x);
}
//构造代码块
{
int y = 200 ;
System.out.println(y) ;
}
//有参构造方法
public Code(String name){
System.out.println("code"+name);
}
//静态代码块
static{
int y = 2000 ;
System.out.println(y);
}
}
//测试类
public class CodeDemo {
public static void main(String[] args) {
int x = 10 ;
System.out.println(x);
//局部代码块
{
int y = 20 ;
System.out.println(y);
}
// System.out.println(y);
System.out.println("----------------------------------------------") ;
//通过无参构造方法创建Code类对象
Code code = new Code() ;
Code code2 = new Code("hello") ;
}
}
2.继承
继承:
将多个类的共性内容抽取出来,放在一个独立的类中,让这个独立的类和其他类产生一种关系
"继承"---关键字 extends
格式:
class 父类名{
共性内容:姓名,年龄.....
提供公共的访问方法setXXX()/getXXX()
}
class 子类名 extends 父类名{}
继承的好处:
1)可以提高代码复用性
2)可以提高代码的维护性,后期便于维护,针对子类和父类进行维护(子父关系明确)
3)类与类产生的继承关系,是后面讲"多态"的前提条件;
在Java中有一个开发原则 "低耦合,高内聚"(以后所有的Java设计模式都需要遵循这一个原则)
耦合性:开发中是永远避免不了,可以降低(耦合:类和类的关系)
内聚性:指的是某个类完成某个功能的一种能力; 尽量不要产生继承关系来完成一个功能,一个类能完成一个类完成;
低耦合:降低耦合性,减少类和类的关系;
继承的特点:
1)在Java语言中,类和的类的关系是一种继承关系,这个继承只能支持"单继承",不支持多继承
class 父{}
class 父2{}
class 子 extends 父,父2{} 多继承:不支持
class 子 extends 父{} :正常的语法格式
2)类和类关系,虽然不支持多继承,但是层层单继承----> 多层继承
注意的问题:
1.子类继承父类,对于非私有的成员,直接可以继承过来,但是如果私有成员,它可以通过公共的访问可以访问,但是直接访问的;
2.被私有修饰的东西(成员变量/成员方法),只能在当前类访问的;
在继承关系中,构造方法的访问问题(重点)
子类继承父类,子类的所有构造方法都默认访问父类的无参构造方法
为什么?子类继承父类,会用到父类的数据,需要让父类先进行初始化; 一个类初始化的---肯定需要执行构造方法的
面试题:
如果一个父类存在有参构造方法,没有无参构造方法,子类的所有构造会出现什么问题?出现了问题,怎么解决?
子类的所有全部构造方法报错,为什么? 子类继承父类,子类的所有构造方法都默认访问父类的无参构造方法
方案1:
1)手动给出无参构造方法
2)假设,人家现在就不需要让你给出父类的无参构造方法;
就需要让子类的构造方法,显示的访问父类的有参构造方法
----要使用关键字 super:代表父类空间标识(代表的父类对象的地址值引用!)
super() :访问父类的无参构造方法
super(xxx) :访问父类的有参构造方法
这些super一定是在子类构造方法中的第一句话
3)保证子类的所有的构造方法某一个构造方法,让父类初始化完毕即可;
先通过子类的无参构造方法里面---this(xxx):访问本类(子类)有参构造方法
在子类的有参构造方法的第一话:让父类初始化 super(xxx):间接访问父类的有参构造方法
子类继承父类,一定要先执行父类的构造方法,初始化完毕之后;然后才能执行子类的构造方法---分层初始化
3.static
static关键字的特点:
1)被静态修饰的随着类的加载而加载,优先于对象存在;
2)不能和this共存;
3)本身含义就是共享,共用;可以多个对象共享共用;
这也是告诉我们,什么将某个属性定义static
举例: 饮水机的水----共享,共用
自己水杯中的水---不行的
或者说:三个窗口同时出售100张电影票, 100张票被三个窗口共用;
4)被静态修饰的成员变量或者成员方法(静态变量/静态方法) (掌握)
访问的方式:
可以使用对象名来访问
但是,对于系统来说(jvm)静态的东西:变量/方法
都是类名直接访问;
类名.变量名;
类名.方法名()
上次用的java.lang.Math
public static double random()
Math.random() ;
静态的使用场景适用于范围:(记忆的)
简单记忆:静态只能访问静态;
静态方法中只能访问静态变量
静态方法只能调用静态方法;
非静态方法皆可以访问静态的东西也可以访问非静态的东西;
day14
1.静态代码块,构造代码块,构造方法的优先级
每次执行构造方法之前,如果存在构造代码块,先执行构造代码块
静态代码块,随着类的加载而加载,类加载一次,静态代码块执行一次!
静态代码块 > 构造代码块 > 构造方法
2.static关键字的特点
1)随着类的加载而加载,优先于对象存在
2)不能和this共存
3)本身概念:体现 共享,共用;对个对象共用某个静态修饰的东西
4)访问方式:类中静态的东西----> "类成员",直接推荐方式,使用类名访问
类名.变量名;
类名.方法名() ;
静态只能访问静态
3.继承以及继承的好处
将多个类的共性内容,抽取到一个独立的类中,让这多个类和这个独立的类产生一种关系,这种关系---"继承关系"
继承的好处:
1)提高代码的复用性
2)提高代码的维护性
3)类和类的关系,是多态的前提条件;
4.继承的特点
在Java中,类和类的关系,只支持单继承,不支持多继承但是,可以多层继承;
5.子类继承父类,构造方法如何访问
构造方法是不能继承的,子类的通过super()默认访问父类的无参构造方法
子类继承父类,子类的所有构造方法默认访问父类的无参构造方法;
实际开发中:写代码的时候
子类继承父类:
子类的无参构造方法----默认父类无参
子类的有参构造方法---直接访问父类有参构造方法
6.继承中成员方法的关系问题
成员方法名称不一致,分别访问即可;
子类继承父类,如果子类出现了和父类一模一样的方法,子类的方法会将父类的方法覆盖了, 方法重写;
7.方法重写override和方法重载overload什么区别
方法重写:出现在继承中, 描述的子类继承父类的时候,可能沿用父亲的功能,而且使用自己的功能,
将父类的功能进行覆盖(复写/重写); 为了让子类具体体现出来的功能信息
举例
动物类 :eat()---->动物饿了都需要吃饭
猫类和狗类:----将eat()方法重写,只有看到具体的动物,才能知道具体吃什么,应该在子类具体体现,将父类的eat重写;
方法重载: 定义方法的时候,方法名相同,参数列表不同,与返回值无关;
目的为保证这个方法它的扩展性问题,同一个方法,可以不同类的参数;
java.lang.Math
求绝对值的方法
abs(int a)
abs(double a)
day15
1.继承中成员变量的访问问题
子类继承父类,如果子类的成员变量名称和父类的成员变量名称不一致,分别访问即可;
如果子类的成员变量和父类的成员变量名称一致:
1)先在子类的局部位置找,是否存在,存在,就使用;
2)如果子类的局部位置没有,在子类的成员位置中找,是否存在,存在就使用;
3)如果子类的成员位置也没有,然后再父类的成员位置找,是否存在,存在就使用;
4)如果父类的成员位置也没有,(父类没有它的父类),就报错,整个类中没有变量;
遵循 "就近原则"
2.继承中成员方法的访问问题
子类继承父类,成员方法(公共方法)名称不一致,分别调用即可 ;如果成员方法名一样,系统认为子类需要重写父类的方法,必须保证子类的方法和父类一模一样
---->子类将父类的方法覆盖.方法重写,访问子类的功能;
如果创建对象的时候,创建的父类对象
Fu fu = new Fu() ; fu .方法名() ;
访问的父类的成员方法
3.final关键字
final:表示最终的,无法更改的,状态修饰符;
修饰类,该类不能被继承
修饰变量,此时变量是一个常量
编译时期常量 : final修饰的基本类型,基本数据类型的数据值不能在改变 (不需要jvm加载)
public static final int num = 100 ;
运行时期常量: final修饰的引用类型数据,引用类型:类,数组,接口 都需要加载
地址值不能在改变
public static final Integer i = new Integer(100) ;
修饰成员方法,该方法不能被重写
4.多态的前提条件以及成员访问特点
多态的前提条件:
1)必须有继承关系
2)存在方法重写
3)父类引用指向子类对象 Fu fu = new Zi() ; 向上转型
Fu fu = new Zi() ;
多态的成员访问特点:
1)成员变量: 编译看左,运行看左
2)成员方法:编译看左,运行看右,存在方法重写
3)静态的方法:算不上重写,跟类相关的,编译看左,运行看左;
4)构造方法:分层初始化,先执行父类初始化,在执行子类初始化
5.多态的弊端
不能访问子类的特有功能;
多态的格式:
Fu fu = new Zi() ; //向上转型
解决方案
1)创建具体的子类对象
Zi zi = new Zi() ; //Zi:子类名
不好:需要重新开辟堆内存空间,消耗内存空间;
2)向下转型
Zi z = (Zi)fu; //符号强转的语法
z.特有功能() ;
不需要单独去开辟堆内存空间
day16
1.多态的好处
1)可以提高代码的复用性,有继承关系保证
2)可以提高代码的扩展性,由多态保证(父类引用指向子类对象)
多态第二个好处:是以后经常写的
1)方法的形式参数传递的是一个引用类型(存在子父关系)一定会使用父类型,调用方法的时候,实际参数传递这个父类的子类对象;
2)方法的返回值问题: 返回的父类型---->需要父类的子类对象;
2.如果在使用多态时出现ClassCastException,说明什么?
ClassCastException :属于运行时期异常的一种; 代表"类转换异常"
使用多态操作向下转型的时候(使用不当),堆内存中 信息和栈内存信息没有子父关系
Animal a = new Cat() ; //堆内存是猫 猫是动物
//Cat c = (Cat)a; //还原成猫 猫是猫
Dog d = (Dog)a ;//语法没有问题,但是内存中有问题 (猫是狗,错误的)
3.抽象类以及抽象类的成员特点
抽象类如何实例化
有抽象方法(在具体的事物中才能能具体的行为)的类一定是抽象类;
public abstract 返回值类型(参数类型 形式名称.,...) ;
抽象类的成员特点:
成员变量:可以是变量,也是自定义常量
成员方法:可以存在抽象方法,也可以存在非抽象方法
构造方法:可以存在无参/有参构造方法;分层初始化:先父类初始化,然后再是子类初始化;
抽象类不能实例化:不能new对象
所以通过抽象类多态来实例化,通过具体的子类进行实例化
抽象类名 对象名 = new 具体的子类名() ;
4.接口以及接口和子实现类的关系
接口:体现的是一种额外功能, 设计理念 "like a"的关系
接口和子实现类的关系:implments 实现
//接口
interface Mary{
//成员方法:只能是抽象方法
public abstract void mary() ;
}
//子实现类
class You implements Mary{
public viod mary(){
System.out.println("结婚了,很开心....") ;
}
}
class Test{
public static void main(String[] args){
//接口比抽象类还抽象:抽象类都不能直接new对象,接口也不能
实例化
//接口多态:接口名 对象名 = new 子实现类名() ;
Mary mary = new You() ;
mary.mary() ;
}
}
5.abstract不能和哪些关键字使用
抽象类不能实例化,而且它是强制子类必须重写抽象方法;
1)abstract不能和 static使用:
static被类名访问.跟类相关,静态方法算不上方法重写;
2)不能和private使用:
被private修饰的:只能在当前类访问
而abstract修饰的方法需要被子类重写
3)不能和final使用
被final修饰的成员方法,不能被重写; (有的jdk源码中会看到)
abstract修饰的方法必须子类重写;
6.接口和抽象类的区别
1)成员的区别
成员变量:
抽象类:
可以是变量,也可以是自定义常量
接口:
成员变量只能是常量: 存在默认修饰符 public static final 修饰的 ,可以省略
成员方法:
抽象类:
即可以是抽象方法,也可以是 非抽象方法
接口:
只能是抽象方法,存在默认修饰符:public abstract :可以省略
构造方法:
抽象类:
既可以存在无参构造方法/有参构造方法,存在继承关系,分层初始化
先父类初始化,再是子类初始化(子类需要用到父类中)
接口:
没有构造方法的 ,意义:就是通过接口暴露给外面功能,实现这些功能接口
2)关系区别
Java中最基本的单元是类,Java本身就面向接口编程
类和类:继承关系 extends,Java语言中只支持单继承,不支持多继承,但是可以多层继承
类和接口: 实现关系 implements;一个类继承另一个类的同时,可以实现多个接口
接口和接口:继承关系:extends 不仅支持单继承,也可以多继承!
3)设计理念的区别
抽象类:
存在继承关系, 体现的是一种"is a"的关系 ,什么是什么的一种
A类是B类的一种,B类是A类的一种 ,这个时候要使用继承;
接口:
子实现类 实现关系,体现的一种"like a"的关系,什么像什么的一种额外的扩展功能 ;