一,匿名对象
定义: 没有名字的对象.
意义: 节省代码,并且很多情况下是针对某个方法只需要调用一次的情况下。
匿名对象可以调用方法,也可以给成员变量赋值。 同时也可以作为方法的参数进行传递。主要的作用就是节省代码量,使代码结构更优雅。
匿名对象的应用:
packageday_06;
public class ClassDemo1 {
public static void main(String[] args) {
Person person=new Person();
person.age=21;
person.name="阿聪";
person.Speak();
new Person("阿聪",21).Speak();//匿名对象可以调用构造有参函数,可以给成员变量赋值,
Person person1=new Person();
person1.intPerson(person1);
person1.Speak();
((Person) intPerson(new Person())).Speak();
}
private static Object intPerson(Person person1) {
person1.name="小葱";
person1.age=20;
return null;
}
}
class Person{
int age;
String name;
Person(){//定义构造函数
}
Person(String nameParm,int ageParm){
name=nameParm;//匿名对象可以给成员变量赋值,
age=ageParm;//匿名对象可以给成员变量赋值,
}
void intPerson(Person person1){
person1.name="小葱";
person1.age=20;
}
void Speak(){
System.out.println("speak:" + name +"的年龄是" + age);
}
}
二. 封装(private)
1.概念: 隐藏对象的属性和细节,仅对外提供公共的方法进行访问。
a, 当类的成员变量使用private 修饰符修饰,那么就不可以直接访问到该成员变量.
b, 当使用private 修饰的成员变量或者成员方法,仅能在本类中使用
c, private 对于main 方法的修饰,也是可以产生作用的.
# javaBean: 是这样一类的类:
他的所有成员变量都使用private 进行修饰,并且对外提供可访问的设置值和获取值的set,get方法。不同的应用场景,可能命名不同,数据库的应用中称为POJO类.
#javaBean与private的应用:
public class DemoBean {
public static void main(String[] args) {
Person person=new Person();
person.setAge(21);//在类person中age被private修饰,所以不能直接用对象调用(person.age=21;是错误的写法)
person.setName("阿聪");//在类person中name被private修饰,所以不能直接用对象调用(person.name="阿聪";是错误的写法)
person.speak();
}
}
class Person{
private int age;//类中的成员变量别private修饰,不能直接访问该成员变量.
private String name;//类中的成员变量别private修饰,不能直接访问该成员变量.
void setAge(int age){
this.age=age;//将主函数的形参21传递给实参age,然后传递给当前对象的应用(this.age)
}
int getAge(){
return this.age;
}
void setName(String name){
this.name=name;
}
String getName(){
return this.name;//将主函数的形参"阿聪"传递给实参name,然后传递给当前对象的应用(this.name)
}
void speak(){
System.out.println("喊出自己的名字:" + name + "和自己的年龄:" + age);
}
}
2.main方法细节:
a.每个类中都可以存在main方法,但是当执行的时候,会优先查看public 的class 中是否有main 方法.
b.如果没有public 的class, 那么会按照文件名优先查找类中的main方法
c.必须定义为public.
三. 优先原则:
优先原则: 对于一个类的成员方法来说,如果传递的形参的变量名称和类的成员变量名称相同,jvm在处理的时候优先当做方法的形参来处理.
四. this 关键字
1.含义: 代表了当前对象的引用. 可以理解为,当前谁来调用,那么方法中的this 就代表谁。(对于成员变量可以区分出来的场景,this 可加也可以不加,实际效果相同。
但是对于实现javaBean/POJO 来说,我们建议都加上在setXXX,getXXX方法中.)
this: 可以加在成员变量的前面来指定对应的引用,也可以加在成员方法的前面。
五. 初始化类成员变量的方式
a.在定义成员变量的同时进行赋值.
b.提供外界可访问到的方法,在方法中进行赋值.
c.通过构造方法进行赋值.
#三种对变量进行赋值的方式以及变量优先原则和this关键字的综合应用:
packageday_06;
public class DemoClassTest {
public static void main(String[] args) {
//第一种方式:
//在构造方法执行前进行赋值,并且该类每个实现的对象,都会被初始化为该值.
//意义: 当我们真的需要一个类的所有对象某些成员变量的值一致的时候。
Person2 per1=new Person2();
per1.name="小聪";
per1.showname();
//第二种方式
//构造方法中直接进行赋值.
//意义:可以在创建对象的同时进行赋值,同时还可以动态的指定设定的值是什么
Person2 per2=new Person2(21);
System.out.println("------------");
per2.showname();
System.out.print("年龄为:");
per2.outputAge();
//第三种方式
//通过调用某个设置值的方法进行赋值,在对象创建完成之后
//意义: 动态的修改成员变量的值.
Person2 per3=new Person2( );
System.out.println("------------");
per3.setAge(21);
per3.eat();
}
}
class Person2{
int age;//该成员变量无法被此类以外的类访问.
static String name;
//优先原则: 对于一个方法来说,如果传递的形参的变量名称和类的成员变量名称相同,jvm在处理的时候优先当做方法的形参来处理.
Person2(){
}
Person2(int age){
this.age=age;
}
void setAge(int age){
this.age = age;
}
int getAge(){
return this.age;
}
void eat(){
System.out.println("eat :"+this.age);
speak();
}
void outputAge(){
System.out.println(this.age);
}
void speak(){
System.out.println("speak!");
}
void showname(){
System.out.println("名字叫:"+ name);
}
}
六. Static
a.随着类加载而加载,静态方法区中来保存静态成员变量
b.优先于对象创建, Person.className = "java";
c.被类的所有对象共享, 静态的成员变量会保存在该class的静态方法区中,所以每个对象看到的都是同一份.
d.可以通过类名来访问也可以通过对象名来访问。
e.推荐通过类名来访问
f.静态的成员,一般称为类相关的成员。
g, static 修饰符既可以修饰成员变量,也可以修饰成员方法。 且修饰之后,就可以通过类名来直接访问到。
h.静态方法中只能访问静态成员变量和静态方法。非静态方法既可以访问静态成员和方法也可以访问非静态成员和方法。非静态虽然可以访问静态的方法,但是不建议这样做。
i,在类中,用static声明的成员变量为静态成员变量,它为该类的公用变量,在第一次使用时被初始化,对于该类的所用对象来说,static成员变量只有一份.
j,用static声明的方法为静态方法,在调用该方法时,不会讲对象的引用传递给它,所以在static方法中不能访问非static成员,static方法不再是针对某个对象的引用,所以不能访问非static成员.
K,可以通过对象引用或者类名(不需要实例化)来访问静态成员.
七. main方法.
修饰符 返回类型 方法名 (参数列表){ }
public static voidmain(String[] args){ }
public: 最大的一个访问权限,使得jvm能够成功调用
static: 类相关的,与对象无关. 类名.main([]);
public class A{
main(){
System.("");
}
}
void: 不需要返回值.
方法名: main
参数列表: 执行的时候,可以传递参数.
八. 工具类.
全部都是静态的方法。所以可以通过 类名.functionName() 方式来访问。
例如:在java.util.Arrays类中,对方法sort(int[] a)的调用,此方法是static void修饰的,所以直接用类名调用(Arrays.sort(a));
一般的话,都会对默认构造方法进行私有化处理,来防止别人使用时习惯性的创建对象来调用方法。
#工具类的综合应用:
public class ToolsClass {
public static void main(String[] args) {
Square square=new Square();
square.setLength(5);
System.out.println("正方形的周长为:" + SquareUtil.getCircumLength(square));
System.out.println("正方形的面积为:" + SquareUtil.getArea(square));
}
}
class Square{
private int length;
void setLength(int length){
this.length=length;
}
int getLength(){
return this.length ;
}
}
class SquareUtil{
private SquareUtil(){//一般的话,都会对默认构造方法进行私有化处理,来防止别人使用时习惯性的创建对象来调用方法。
}
static int getCircumLength(Square square){//全部都是静态的方法。所以可以通过类名.functionName() 方式来访问。
return 4*square.getLength();
}
static int getArea(Square square){//全部都是静态的方法。所以可以通过类名.functionName() 方式来访问。
return square.getLength()*square.getLength();
}
}
九. 代码块
概念: 使用{} 括起来的代码,称为代码块
分类: 根据它位置和声明的不同,我们可以将代码块分为局部代码块,构造代码块,静态代码块,同步代码块(多线程涉及).
a .局部代码块:限定了变量的生命周期,变量在局部代码块中定义的,那么出来局部代码块之后,就访问不到了。在局部代码块中定义的变量,在出了代码块之后,内存就会释放掉。
作用: 主要就是节约内存.
#:局部代码块中定义的变量,虽然说作用域是局部的,但是如果存在外部嵌套的代码块,且在局在局部代码块定义之前就定义了某个变量,那么在我们局部的代码块中就不可以定义相同名称的变量。但是如果在局部代码块执行之后,去定义一个和局部代码块中相同名称的变量,是可以的。因为局部代码块中的变量已经失去了作用域范围。
b.构造代码块: 类中方法外出现,每次调用构造方法的时候,都会优先先调用构造代码块。
特点: 每创建一个对象,都会调用一次我们的构造代码块.
作用: 如果存在很多重载的构造方法,而且每个里面需要执行 相同的逻辑,那么就可以考虑将这些代码提取到构造代码块中来执行。让我们代码结构更简练。增强了维护性.
c.静态代码块: 类中方法外出现,但是用static 来进行修饰。
特点: 随着类加载的时候执行。
用处: 适用于整个软件的生命周期中,只需要执行一次的业务逻辑代码。
#:static代码块和构造代码块的综合应用:
public class DaiMaKuai {
static{
System.out.println("执行了主类的静态代码块");//static代码块适用于整个软件的生命周期中,只需要执行一次的业务逻辑代码。
}
public static void main(String[] args) {
Person person=new Person();
System.out.println("---------------");
Person person1=new Person(20);
}
}
class Person{
int age;
static{
System.out.println("执行了Person类的静态代码块");//static代码块适用于整个软件的生命周期中,只需要执行一次的业务逻辑代码。
}
{
System.out.println("执行了构造代码块");//构造代码块:每创建一个对象,都会调用一次我们的构造代码块.
}
Person(){
System.out.println("执行了无参的构造函数");
}
Person(int age){
this.age=age;
System.out.println("执行了有参数的构造函数,同时打印出年龄:" + this.age);
}
}
十:继承
特点: 1. 子类继承父类,继承父类的成员变量和成员方法。但是他们各自拥有的各自的成员变量,所以他们的值,并不会继承。
2. 对于父类中的私有成员变量和私有方法,子类是无法继承的。
继承优点: a.提高了代码的复用性; b.提高了代码的维护性
继承缺点: a.类的耦合性增强了。
开发的原则: 高内聚,低耦合.
耦合: 类和类之间的关系; 内聚: 自己独立完成某件事情的能力.
3.只支持单继承,但是可以支持多层继承;继承是相互叠加的,子类继承的时候,会递归似的寻找父类中是否还存在继承,会继承整个层级直到最根部类的属性和方法。
#继承的综合应用:
public class ExtendsDemo2{
public static void main(String[] args){
GrandFather gFather = new GrandFather();
gFather.speak();
Father father = new Father();
father.speak();
father.eat();
Son son = new Son();
son.eat();
son.sleep();
son.speak();
}
}
class GrandFather{
void speak(){
System.out.println("speak");
}
}
class Father extends GrandFather{//只支持单继承,但是可以支持多层继承,子类继承的时候,会递归似的寻找父类中是否还存在继承,会继承整个层级直到最根部类的属性和方法。
void eat(){
System.out.println("eat");
}
}
class Son extends Father{//只支持单继承,但是可以支持多层继承,子类继承的时候,会递归似的寻找父类中是否还存在继承,会继承整个层级直到最根部类的属性和方法。
void sleep(){
System.out.println("sleep");
}
}
4.对于构造方法是无法继承的。但是有办法可以调用父类的构造方法。
继承关系中访问成员变量:
a.不同名的成员变量: 子类可以直接访问和使用父类继承的非私有的成员变量.
b.同名的成员变量: 优先原则: 如果子类中定义了和父类中相同名字的成员变量,会优先访问子类的该变量,如果想要依然访问到父类中的同名变量,我们需要加上super关键字来获取.
this: 当前对象的引用, 可以访问到子类中的变量,也可以访问到父类中的变量; super: 父类对象的引用, 访问父类中的变量
继承关系中访问成员方法:
a.不同名的方法: 子类可以直接调用到父类的方法
b.同名的方法: 当父类和子类出现同名方法的时候(同名方法: 指的返回值类型(父子类关系是可以的),方法名称以及方法接收的形参列表要一模一样)
#:在这种情况下: 当我们子类调用该方法时,会有优先原则的处理,就是会调用子类的该方法。
方法的重写: 存在于继承关系中,子类中定义的方法和父类中的方法完全一样的时候(返回值类型父子类关系是可以的),我们在通过子类对象来访问该方法的时候,就会调用到子类的方法。
方法重写注意事项:
子类不能重写父类的私有方法.
子类重写父类方法的时候,提供的访问权限不能更低.
子类覆盖父类方法,如果父类是静态方法的话,子类也必须是静态方法才可以成功覆盖,也就是重写。
#方法重写的综合应用:
public class ExtendsDemo2{
public static void main(String[] args){
Square square=new Square();
System.out.println("正方形的周长为:" + square.getSumLength());
System.out.println("正方形的面积为:" + square.getArea());
System.out.println("----------------");
Rectangle rectangle=new Rectangle();
System.out.println("长方形的周长为:" + rectangle.getSumLength());//方法的重写,子类对象调用的是自身的方法
System.out.println("长方形的面积为:" + rectangle.getArea());//方法的重写,子类对象调用的是自身的方法
}
}
class Square{
private int length=8;
int getSumLength(){
return 4*length;
}
int getArea(){
return length*length;
}
}
class Rectangle extends Square{
int width = 4;
int height = 5;
int getSumLength(){
return 2*(width+height);
}
int getArea(){
return width*height;
}
}
方法重载:
同一个类中,如果我们有多个相同方法名的方法,但是他们的形参列表是不同的,那么这种方式我们就称为方法的重载。在调用的时候,jvm能够通过不同的形参来区分到我们到底调用的是哪个方法。
关于方法重写和方法重载的返回值约束:
方法重载: 仅返回值不同是不能重载的。必须参数列表不同。
方法重写: 返回值类型(父子类关系是可以的) 要求返回值类型也要相同的.
this: 可以访问子类的方法,也可以访问父类的方法。
super: 只能够访问父类的方法。
#:补充: 一个文件在编译之后产生的.class 文件的数量,取决于在该文件中定义的class的数量。(非内部类) 而且是不引入其他类的情况下。
继承中构造方法的调用:
特点: 1. 创建子类对象的时候,一定会优先去创建父类的对象。 因为要创建父类对象,所以就需要去调用到父类的构造方法.
2. 对于我们所有的类的构造方法的第一行,第一行在我们没有自己添加this(...)或者super(...)的情况下都会去帮我们默认的添加super()
#:如果父类中不存在默认的构造,子类依然要创建对象,那么子类就需要显示的指明调用的是哪一个父类对象,才能保证父类对象创建的成功。
明确一点: a.一定要保证父类对象的创建成功.
b,构造方法的第一行,如果我们添加了自己调用的this(...),或者super(...), 系统就不会为我们默认的添加super().
c, 我们的this(...)或者super(...) 必须放到第一行。二者只能有其一。
d,子类的构造过程中,必须要去调用父类的构造方法.(用super.+构造方法)
e,子类可以在自己的构造方法中用super(参数列表)来调用父类的构造方法.
(1)使用this(参数列表)来调用本类中其他的构造方法,
(2)使用super(参数列表)来调用弗雷中的构造方法时,必须放在子类构造方法的第一行.
f,如果子类的构造方法没有显示的调用父类的构造方法,系统会默认的调用父类中无参的构造方法.
g,如果子类的构造方法既没有显示的调用父类中无参的构造方法,而父类中又没有无参的构造方法,则会编译出错.
#继承中构造方法的调用综合应用:
public class JiChengMethod {
public static void main(String[] args) {
Student student=new Student();
}
}
class Person{
int age;
Person(){//父类无参的构造函数
System.out.println("通过子类构造器中,的super()调用父类的构造方法");
}
Person(int age){
this.age=age;
}
}
class Student extends Person{
Student(){
super();//调用子类构造的过程中,必须会调用父类的构造方法,并且必须用super(参数列表)来调用父类的构造方法,还要放在子类构造方法的第一行.
//super(21);
System.out.println("调用子类的无参构造方法");
}
Student(int age){
super();
//super(22);
}
}
十一: final关键字
a.final修饰类: final如果修饰一个类,该类不能被继承.
b.final修饰类的成员变量: 该成员变量的值不可修改。
#如果需要对这个变量的值进行初始化:
a.构造代码块中可以进行初始化
b.构造方法中可以进行初始化
c.定义成员变量的时候,可以直接进行初始化
注意一点: 这三种方式同时只能用一种。在大多数的场景下,我们的final成员变量都会配合public static 一起使用.
//常量类, 变量命名都要大写,而且单词之间要用_分割开.列 classA{
public static final double ShuXue =86.05;
}
静态成员变量的初始化时机:
a.在创建静态final成员变量的时候,直接进行初始化。
b.在静态代码块中进行初始化.