1、对象与引用
引用类型:除了基本类型之外的变量类型
Java中的对象是通过引用对其操作的
值传递和引用传递
Java中进行方法调用传递参数时,参数传递有两种:
值传递:(形参数类型是基本数据类型)
引用传递:在传递时,传的是对象地址
变量分类:
按照数据类型分类:
基本类型:8个 byte short int long float double char boolean
引用类型:数组,String,自定义的类
new Person("张三",22); 在堆空间创建并存的对象
Person zs 在栈空间中声明的一个变量
= 把对象在内存中的地址 赋给 左边的变量,左边的变量只算持有对象的引用地址
public class TexsPerson {
public static void main(String[] args) {
//创建对象
Person zs = new Person("张三",22);
zs.showInfo();
Person ls = new Person("李四",20);
ls.showInfo();
Person ww = new Person("王五",21);
ww.showInfo();
}
}
基本类型传递
public class Demo {
public static void main(String[] args) {
Demo d = new Demo();
int a = 10;
d.test(a);
System.out.println(a);
}
//形参b,用实参a的值,直接对b进行赋值,在内存中有两个独立的存储空间a,b
public void test(int b) {
b = 20; //b的值发生改变,不会影响到a的值
}
}
引用类型 在传递时,传的是对象地址
public class Demo {
public static void main(String[] args) {
Demo d = new Demo();
Person zs = new Person("张三",20);
d.test(zs);//只是把对象的地址传递给了p
System.out.println(zs.name);//李四
}
public void test(Person p) {
p.name = "李四";
//p和zs指向的是同一个对象
}
}
2、static关键字
this关键字:
this关键字代表当前对象
使用this关键字引用成员变量
使用this关键字引用成员方法
在一个类的方法或构造方法内部,使用'this.成员变量名'的格式引用成员变量名,用于区分同名的成员变量和局部变量。
static关键字:
static被称为静态,可以用来修饰类的属性,方法,代码块,内部类等。
随着类的加载而加载
优先于对象存在
修饰的成员,被所有对象所共享
可不创建对象,直接被类调用
static属性:
静态属性是类的所有对象共享的,不管创建了多少对象,静态属性在内存中只有一个。
static方法可以使用对象调用,也可以直接用类名调用。
在static方法内部只能访问类的static属性,不能访问类的非static属性,static属性先加载。
public class Chinese {
String name;//name属性不建议修饰为static,在内存中只有一份,而name对象每个都不一样
int age;
static String country = "中国";//常量一般修饰为static
/*
static修饰方法,类方法,静态方法不能使用非静态的成员变量,
静态资源随着类先加载,非静态资源随着对象的创建而加载
*/
public static void test() {
//System.out.println(name);
}
public void text1() {
System.out.println(country);
}
/*
非静态方法可以使用静态变量,非静态方法必须通过对象来调用,对象创建之前先加载类
*/
public static void main(String[] args) {
Chinese zs = new Chinese();
zs.name = "张三";
zs.age = 20;
Chinese ls = new Chinese();
ls.name = "李四";
ls.age = 20;
Chinese.country = "china";
System.out.println(zs.name);
System.out.println(ls.name);
System.out.println(zs.country);
System.out.println(ls.country);
Chinese.test();//静态方法,静态变量,建议使用类名调用
}
}
3、代码块
代码块:类似一个没有名字的方法
类什么时候加载?
main方法在哪个类中执行,这个类加载的
创建某个类的对象,
调用某个类中静态的属性,方法
实例块:每次创建对象时自动调用,在创建对象之后执行,调用构造方法之前执行,每创建一次对象,执行一次
{
//任何符合语法的Java代码
}
静态块:类加载时自动调用,在类加载时执行,只执行一次,多个静态按照先后顺序
static {
//任何符合语法的Java代码
}
public class Demo {
String name;
static String country = "中国";
public Demo() {
System.out.println("无参构造");
}
{
System.out.println("实例代码块");
}
static{
System.out.println("静态代码块2");
}
static{
System.out.println("静态代码块1");
}
public static void main(String[] args) {
new Demo();
new Demo();
System.out.println(Demo.country);
System.out.println(Demo.country);
}
}
4、包
包:
为了更好地组织类,java提供了包机制,用于区别类名的命名空间(是类路径的一部分)
包的作用:
避免类重名
按照不同的功能管理类
控制访问权限
包的命名规范:
使用. 来区分包的级别;包名一般小写
第一级:项目类型
第二级:项目开发或运行的公司名
第三级:项目名称
第四级:项目模块名称
导入外部包的类:使用关键字 import
5、访问权限修饰
public、protected、private、(default)
Java四个访问权限修饰符,权限从大到小:
1、public:公共权限 修饰类、属性、方法。可以被任意类访问;
2、protected:受保护的权限 修饰属性、方法。
可以被同包类访问,如果不是同包类,必须是该类的子类才可以访问。
3、default:(默认的)同包访问 修饰类、属性、方法,必须是该类的子类才可以访问。
4、private:私有权限 修饰属性、方法。 只能在本类中访问。
public class Demo01 {
public String pubname;
protected String proname;
String name;
private String priname;
public static void main(String[] args) {
Demo01 demo01 = new Demo01();
System.out.println(demo01.pubname);
System.out.println(demo01.proname);
System.out.println(demo01.name);
System.out.println(demo01.priname);//在本类中都可以访问到
}
}
public class TestDemo01 {
public static void main(String[] args) {
Demo01 demo01 = new Demo01();
System.out.println(demo01.pubname);
System.out.println(demo01.proname);
System.out.println(demo01.name);
//System.out.println(demo01.priname);
//在同包的其他类中只能访问 公共的,受保护,默认的;
//私有权限只能在自己类中访问,同包其他类也不能访问
//在不同包的子类中可以访问父类受保护成员
}
}
6、面向对象特征
面向对象语言的三大特征:
封装
继承
多态
面向对象的特征--封装
封装:
将类的某些信息隐藏起来(用到访问权限修饰符来实现),不让在外部直接对其访问,可以通过一个特定的方法来对隐藏的信息进行访问,便于控制。
设计模式:
解决某一类问题的解决方案(模式)
单例模式-->让一个类在一个程序,只能创建一个对象
具体表现:使用不同的访问权限
public class Dog {
//隐藏类的属性
private String name;
public Dog(){
}
public Dog(String name) {
this.name = name;
}
public void eat(){
}
//特定的方法,对隐藏成员进行访问
public void setName(String name){
this.name = name;
}
public String getName(){
return name;
}
}
public class DogTest {
public static void main(String[] args) {
Dog dog = new Dog("旺财");
//dog.name = "";//直接访问类的成员
Dog dog1 = new Dog();
dog1.setName("羊杂");
System.out.println(dog1.getName());
}
}
public class Window {
/*
将构造方法设置为私有化权限,在其他类中不能随意使用
*/
private static Window window = null;
private Window(){
}
public static Window getWindow(){
if(window == null){
window = new Window();
}
return window;
}
}
public class WindowTest {
public static void main(String[] args) {
Window window1 = Window.getWindow();
Window window2 = Window.getWindow();
System.out.println(window1);
System.out.println(window2);
}
}
面向对象的特征--继承
继承:
从已有的类中派生出新的类,新的类能吸收已有的类的属性和行为,并能扩展出新的能力。
JAVA中extends关键字表示继承关系
JAVA不支持多继承,一个类只能有一个父类
继承之后子类可以调用父类的所有非私有属性和非私有方法
继承是代码重用的一种方式
继承的形式:
[访问权限修饰符] [修饰符] 子类名 extends 父类名 {子类体}
继承具有传递性:
C类从B类继承,B类又从A类继承,那么C类就具有B类和A类的所有非私有属性和非私有方法
当一个没有继承任何一个类时,jvm会默认让类继承Object类,Object是 java为所有类提供的基类
继承中的构造方法:
在创建子类对象后,调用构造方法时,从上向下的调用,先初始化父类信息
使用super() 在子类构造方法的第一行默认执行,调用父类无参构造方法
super() 表示调用父类中的无参构造,默认存在,必须放在第一行
super关键字:
使用super关键字访问父类成员
·用super.成员变量名 来引用父类成员变量
·用super.方法名(参数列表)访问父类的方法
·用super.构造方法(参数列表)访问父类构造方法
误区:勿把super误认为是父类对象,在创建子类对象时不会创建父类对象。
只会将父类中的信息加载到子类对象中存储。
方法的重写(OverRide):
当父类的方法实现不能满足子类需求时,可以对方法进行重写。
在子类中可以根据需要从基类中继承类的方法进行重写。
方法重写的规则:
·方法名相同、参数列表相同;
·返回值类型相同;
·访问权限不能小于父类权限;
注意:构造方法、静态方法不能重写,成员变量不存在重写
在子类中对父类的方法进行重写(覆盖) 对已有的功能进行扩展或覆盖
具体语法:
方法名相同,参数列表,返回值类型相同
访问权限修饰符等于或者大于父类的权限
@override 这是java中提供的一个注解标签(是一种标记 记号)
添加此注解方法标签表示此方法是从父类重写过来的,就会对其进行语法验证
package extend;
/*
动物类---基类()
*/
public class Animal {
//成员变量
private String name;
private int age;
//构造方法
public Animal(){
System.out.println("Animal无参构造");
}
//成员方法,是类的功能
public void eat(){
System.out.println("动物池东西");
}
//为私有属性提供的操作入口
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;
}
}
狗是动物,狗是子类(派生类)
狗类继承动物类
使用extend关键字
一个类只能直接继承一个父类,继承后子类就可以使用父类中非私有成员
在子类中就可以扩展子类持有的属性和方法
public class Dog extends Animal{
private String color;
public void play(){
System.out.println("狗玩");
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
}
public class Test1 {
public static void main(String[] args) {
Dog dog = new Dog();
//调用父类功能
dog.setName("二狗");
dog.setAge(3);
dog.eat();
//调用子类持有的功能
dog.setColor("黑色");
dog.eat();
Cat cat = new Cat();
cat.setName("111");
cat.setAge(2);
cat.eat();
}
}
抽象类
抽象类:
使用abstract修饰,抽象类可能包含了抽象方法
抽象方法:
抽象方法时一种特殊的方法:只有声明,没有具体实现
抽象方法必须用abstract关键字进行修饰
在一些比较靠顶层的类,它的实现与子类大多数不同,此时没必要在顶层实现,只需要声明功能即可
abstract 修饰的方法是抽象方法,没有方法体
public abstract class Animal {
public abstract void eat();
public void sleep(){
System.out.println("动物");
}
}
public class Cat extends Animal{
@Override
public void eat() {
System.out.println("猫吃鱼");
}
}
抽象类的特点:
抽象类只能作为基类,表示继承关系继承抽象类的非抽象类必须实现其中的所有抽象方法,而已实现方法的参数、返回值要和抽象类中的方法一样。否则,该类也必须声明为抽象类。
面向对象的特征--多态
多态:
同一种事务,在不同时刻表现不同的状态
多态存在的三个必要条件:
要有继承(类继承类、类继承抽象类、类实现接口)(前提条件)
要有重写(前提条件)
父类引用指向子类对象
父类引用指向子类对象:
编译期类型是父类,运行期类型是子类;
多态环境下对非静态成员方法的调用:
编译期间看左边、运行期间看右边
public abstract class Animal {
public abstract void eat();
public void sleep(){
System.out.println("动物");
}
}
public class Dog extends Animal{
@Override
public void eat() {
System.out.println("Dog重写eat()");
}
}
......
Animal a = new Dog();
//调用的是子类中的方法
a.eat();
a.sleep();
多态环境下对静态成员方法的调用:
编译期间看左边、运行期间还看左边
多态环境下对成员变量方法的调用:
编译期间看左边,运行期间还是看左边
方法参数具有多态性:提高代码的扩展性。
多态转型
自动转型:子 继承 父
向上转型:子类型 自动转为(上升为)父类类型
Animal dog = new Dog();
向上转型的作用:提高程序的扩展性。
强制转型:向下转型 父类类型 转为 子类自己的类型
向下转型的作用:为了使用子类中的特有的方法
优点:父类引用表示子类对象,提升程序的扩展性
Final关键字
final关键字:
final用于声明属性,方法和类。
属性:定义就必须直接赋值或者在构造方法中进行赋值。
方法:子类里不可重写
类:不能被定义为抽象类或是接口,不可被继承。
对参数做final修饰
在方法参数前面添加final关键字,为了防止数据在方法体中被修改。
接口
使用java接口来实现:
USB接口本身没有实现任何功能;
USB接口规定了数据传输的要求;
USB接口可以被多种USB设备实现;
面向接口编程:
接口存在的意义:
java中一个类只能有一个父类,所以用接口可以实现多继承的逻辑。
接口的本质:
接口是一种特殊的抽象类,这种抽象类中包含抽象方法。
接口和抽象类:都是用于在顶层类,指定规范(设计功能)
jdk8之前 接口只能定义 静态常量 和 抽象方法
jdk8之后 接口增加了静态方法 默认方法
public interface Animal {
//所有属性默认为 public static final
//public static final int num = 10;
int num = 10;//接口中的成员变量默认是静态变量
//抽象方法是 public abstract
//public abstract void eat();
void eat();//接口定义抽象方法
//静态方法 直接通过接口名调用
public static void testStatic(){
System.out.println("testStatic");
}
//默认通过子类调用
public default void testDefault(){
System.out.println("testDefault");
}
}
接口的定义和使用
接口的定义:使用interface关键字来声明一个接口
接口中没有构造方法,不能创建对象
接口名只能调用接口中的静态成员
接口的使用:
类使用implements关键字实现接口。
在类声明中,implements关键字放在class声明后面。
[访问修饰符] class 类名 implements 接口名1,接口名2……{ }
结合继承:
[访问修饰符] class 类名 extends 父类名 implements 接口名1,接口名2……{ }
接口的特性:
接口也表示抽象(功能设计) 也是需要其他类来实现的(继承)
一个接口可以继承多接口
一个类可以实现多个接口
一个类只能直接继承一个类
接口不能实例化对象,无构造方法
当类实现接口的时候,类要实现接口中所有的抽象方法。否则,类必须声明为抽象的类
接口中方法可以是抽象的,静态的,默认的